Tuesday, July 26, 2011

Dropping ReiserFS (v3)

    As the time goes by, Reiser FS v3 is becoming outdated, but this is not the reason I will drop it in the near future in favour of ext4.


    Last night, I was renaming a couple of files (14GiB ones), and my laptop's battery went out.
When I rebooted and after checking disk consistency with reiserfsck, one of those files became empty! (I must explain that that file was not in cache nor it had been written recently, it has been there since I booted)


    This is just unaceptable for a journaled and "modern" file system, and since Hans Reiser is in prison and namesys seems to have discontinued Reiser FS v4 support, I will DROP ReiserFS forever.

Rest in peace ReiserFS

Wednesday, May 04, 2011

PostgreSQL Inhertance and Constraints problem solved!

Warning: Using stored procedures and triggers in PostgreSQL is addictive!

    I've been playing around with stored procedures using PLpgSQL language, just to try performance improvements and they are just addictive!

    For example, PostgreSQL has the ability to inherit all data from one or more tables to other table, but unfortunately, any constraint will be inherited as of 9.0.4, and thus, you can not make a FOREIGN KEY constraint agains parent table.

    Fortunately, you can workaround this issue with a little performance impact by using stored procedures, triggers and a separate table for that constraint.

    For example, imagine this scenario:
CREATE TABLE account (
    id SERIAL,
    username VARCHAR(50) UNIQUE NOT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE employee (
    salary MONEY(6,2) NOT NULL
) INHERITS (account);

CREATE TABLE problematic (
    id SERIAL,
    account_id INTEGER NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (account_id) REFERENCES account(id)
);

    Suppose we have some data:

INSERT INTO employee(username,salary) VALUES ('foo','1280.90'),('bar','3460.75');

    We will have account filled with those usernames as well as employee filed with the rest of values but the problem will come with a:

INSERT INTO problematic(account_id) VALUES(1);

    Since inheritance does not cover constraints, this last INSERT will fail because it will not find corresponding id on account table, despite it is really there.

    But there is NOT all lost! Fortunately we can place triggers on employee to fill and maintain other intermediary table values for simulating that constraint.

    Solution will be to create that table:

CREATE TABLE account_constraint (
    id INTEGER NOT NULL,
    PRIMARY KEY (id)
);

    And to change employee's FOREIGN KEY constraint this way:

FOREIGN KEY (account_id) REFERENCES account_constraint(id);


    And now... how to keep account_constraint table up to date always and in a safe way? The solution rather than code it by yourself in all clients is to use a procedure and place triggers which will fire BEFORE INSERT, UPDATE and DELETE.

    This could be an example of this procedure:

CREATE OR REPLACE FUNCTION account_id_constraint_handler() RETURNS trigger
AS $$
    BEGIN
       IF (TG_OP = 'INSERT') THEN
          INSERT INTO account_constraint(id) VALUES (NEW.id);
       ELSE
          IF (TG_OP = 'UPDATE') THEN
             UPDATE account_constraint SET id=NEW.id WHERE id=OLD.id;
          ELSE
             DELETE FROM account_constraint WHERE id=OLD.id;
             RETURN OLD;
          END IF;
       END IF;
       RETURN NULL;
    END;
$$
Language 'plpgsql';

    And the last thing to do is to set triggers this way:

CREATE TRIGGER insert_accountID
AFTER INSERT ON user_data
FOR EACH ROW
EXECUTE PROCEDURE account_id_constraint_handler();
CREATE TRIGGER update_accountID
AFTER UPDATE ON user_data
FOR EACH ROW
EXECUTE PROCEDURE account_id_constraint_handler();
CREATE TRIGGER delete_accountID
AFTER DELETE ON user_data
FOR EACH ROW
EXECUTE PROCEDURE account_id_constraint_handler();


    You can now alter any data safely maintaining FOREIGN KEY CONSTRAINT!
And the best: database will do all work needed with only a little impact, since PostgreSQL stores procedures in a precompiled state to improve performance a bit.

    Remember that, once you start using stores procedures (or functions) you will not stop as stated in the warning above!

Wednesday, April 20, 2011

Microsoft and its unfair selling techniques


    Microsoft, did it again: left its users alone with new versions of its programs.

    I am referring for example to Internet Explorer 9, new Version of Windows Live Messenger, etc....
Rather than make it compatible with its own older O.S., they just require you to upgrade (and BUY) another version of their O.S.

    This is TOTALLY UNFAIR! Specially taking into account the fact that ANY of its O.S. is FREE, then, the result is that you pay for an O.S. and be left alone in some time if you don't pay again (and thus, forced to pay another O.S.).

    What demonstrate this kind of behavior from Microsoft?
  • They does not value its own customers: you pay, and whenever they say they won't support you, they won't and you can't complain (it is in their TOS).
  • If for any cause, a security risk is discovered or an important upgrade in other program is made, if they don't release it for their O.S., you can't simply have it...
    What means this to me?
  • It makes me happy to be a Linux ONLY user since 7 years now, without using any software from Microsoft.
  • I don't get fooled by a company which requires me to pay for an limited product, full of security holes (in its long history), and full of bugs, and, of course, trapped to pay to them every X years forcedly!
Conclusion: Will you get fooled by Microsoft?

Dropping MySQL, and adopting PostgreSQL

    Finally I had the time to dig a bit this issue, and finally, decided to drop all MySQL support in favor of PostgreSQL.

    Despite PostgreSQL is not as known nor as used as MySQL, it has MANY advantages:
  • Referential Integrity: MySQL's default engine (MyIsam) does NOT support any kind of referential integrity, which could lead to corruption and inconsistencies in DB.
  • On the other hand, the other MySQL's engine which does support referential integrity (InnoDB) is very much slow. In my case, only to create a table with a referenced FOREIGN KEY to another table takes ~1 second! And cascade deleting/checking/updating also takes much more time then postgre takes.
  • Extended Data Types: With PostgreSQL you don't have only a few data types like you have in MySQL. With PostgreSQL you have, cidr (for IP addresses), money, and other data types, as well as user defined data types.
  • Prepared Statements: As stated in my previous post, MySQL had support for prepare statements, but you couldn't not give a name to them (unless you use my class, or code it by yourself), but with PostgreSQL, you can even give natively a string name! (even inside client).
  • Performance: In my case, with my databases, and googling a bit, you can see that PostgreSQL has much better overall performance than MySQL.
    To sum up, I though that since Oracle bought MySQL, it would be improved a lot, but it seems only a commercial action rather than a really interest in MySQL from Oracle.

Thursday, March 03, 2011

MySQL's Prepared Statements made really easy with PHP

    I've been programming a bit with php for first time, realizing that it is true what my friends told me: it is really close to C/C++.


    I managed to have an abstract class to handle and execute SQL's prepared statements, and a bit more that I want to share with world.


    But first, just an example of how I made prepared statements really easy to handle with only inheriting from my MySQLDatabase class! Specially if you program a singleton class for your database connection and let __construct and __destruct do its magic!

    You can really inherit from this class and see how easy is implementing prepared statements in your php project!

Example of usage

    And now... the code itself!

Code for MySQLDatabase class

    I hope someone find it usefull!

Friday, February 11, 2011

About Prepared Statements

    Well, I didn't know much about the benefit of having prepared statements as of today. But thanks to trinitycore I discovered a lot.

    As well as trinitycore (which is a framework for a World of Warcraft server and they do it for learning purposes), I learnt too.

    I saw they were moving to Prepared Statements almost all their queries, and wanted to do so on my own projects (specially php ones).

     If you code in OO paradigm, simply prepare all your statements in __construct, and close them in your __destruct ($stmt->close()) function.

    The benefits were huge:

  • Avoid ALL kind of SQL injection by treating parameters as strictly parameters. This way, even if a given parameter has some kind of SQL operator, it will be treated as a regular string, rather than execute what it contains.
  •  If a prepared statement contains any SQL syntax error (fields not existing, misspelling of a sentence, etc), the STMT object WILL NOT be created, and thus, in destructor, a warning will be raised when you call close function. This way, you can autocheck a sentence WITHOUT actually calling it, and thus, not modifying your database only to check if syntax is OK.
  • Also, you will keep SQL data as FAR as you can, and you can encapsulate even more, and more secure, since the only thing you do to query is TO BIND parameters, instead of writting the whole query. That could help you in a possible future redesign changing the less code as possible.
  • Speed: That query is stored in server only ONCE, and every time you run it, you only send its parameters to server. This way, you save time, bandwidth and you can focus your code in everything but database.


    There are even more benefits, but.. try them by yourself in your projects!

Friday, June 25, 2010

Brightness adjustment on NVidia Cards

    Thanks to nvclock 0.8 which is currently in beta state, we have a great utility: smartdimmer

    This comes into account specially for people (like me) who has some laptop models which is not that easy to adjust screen brightness (in my case, a Sony Vaio which does not work with sonypi).

    With smartdimmer, you can easily increase or decrease screen brightness, or by giving a number between 15 to 100, or by incrementing/decrementing a unit on every call.

    Since only increment/decrement a unit is not enough for a single keypress, I've developed a little script which will increase/decrease 10 units on every call.

    This is the script:


#! /bin/bash

BRIGHTNESS=0

show_error() {
   echo "Usage:"
   echo "$0 increase OR $0 decrease"
}

get_current_brightness() {
   BRIGHTNESS=`smartdimmer -g | awk '{ print $3 }'`
}

increase_brightness() {
   get_current_brightness
   let "BRIGHTNESS+=10"
   `smartdimmer -s $BRIGHTNESS`
}

decrease_brightness() {
   get_current_brightness
   let "BRIGHTNESS-=10"
   `smartdimmer -s $BRIGHTNESS`
}

# programa principal

if ([ -z "$1" ] || [ "$#" -gt 1 ]) || ([ "$1" != "increase" ] && [ "$1" != "decrease" ])
then
   show_error
else
   if [ "$1" == "increase" ]
   then
      increase_brightness
   else
      decrease_brightness
   fi
fi

    You just need to call it with increase or decrease parameter. I hope you find it usefull as I did.