Flex Coding Conventions

This document is intended to set the coding
conventions for the Flex side.

General Requirements

Only the most recent release of Adobe Flex
should be used. Currently the release is “Flex 3”.

Standard object oriented programming principles
must be used in the Flex code development.

A concept for error handling should be provided
and used by the Flex developers.

A concept for security should be provided and

Necessary Development Concepts

The following is a list of necessary concepts for Flex application development:

  • Error handling and reporting.
  • Application security and authentication.
  • Client side input validation. In certain modules, it may be necessary to create concepts for L10N and I18N.

Packages

All package names should be meaningful and
should be prefixed with com.companyname. For example, org.rogerpadilla

When importing packages into classes, it is
preferred to import concrete classes instead of entire packages.

Files

All files must be encoded in the UTF8
format.

  • MXML file names: UpperCamelCase.mxml
  • ActionScript file names: UpperCamelCase.as for classes and all interfaces should be prefixed with I ( IUpperCamelCase.as).

Classes, functions and code

The following is the set of coding rules
for ActionScript:

  • There should not be magic numbers, strings or values present in the code. Easily accessible constants, property files, xml files should be created where all such values will be kept. For example, a remote service URL should not be hardcoded.
  • Each class, function and class property should be commented. Non-obvious blocks of code should be preceded with a commented explanation of what they do.
  • Multiple variables should not be declared in a single line.
  • Multiple statements should not be placed on a single line.

The following is the set of coding rules
for MXML:

  • Use external style files.
  • There should be only one script block per MXML file, and it should follow the same guidelines as usual ActionScript files, because it should be exportable with asdoc.

Documentation

All MXML files should contain a brief
desctiption if what they do and where they are used.

All ActionScript classes, functions and
class attributes should be commented with meaningful information in English. It
should be easy to create a documentation export using Flex’s asdoc tool,
where all packages, classes and functions can be reviewed.

For functions, there should be at minimum a
@param tag for each parameter, @return tag for returned
values, and a description of what the function does.

3 comments March 31, 2009

Te queda una semana de vida. ¿qué vas a hacer con ella?

Imaginen por un momento que alguien les dice que les queda una semana de vida. ¿Qué harían, ante tal perspectiva? La pregunta es peliaguda desde el momento en que se plantea, y a medida que se reflexiona, se entra más a fondo en una espiral en la que parece no existir la respuesta correcta. ¿Pero realmente, qué es una respuesta correcta? Esta es otra interesante pregunta, a la que quizá dedique unas líneas otro día.

Volvamos al asunto. Solamente hay que ponerse en situación. Joder, es una putada, pero esto no es un juego. O bueno, quizá sí, pero el objetivo es conocernos un poco más a nosotros mismos, con lo cual es un juego muy serio, digamos que instructivo. Como el Mecano, vamos. Bien, mucha gente diría que visitaría a sus seres más queridos, que pasaría todo el tiempo con ellos. Otros dirían que eso no le aporta nada, porque cuando desaparezcan nada quedará de ellos y que para cuando desaparezcas ya todo dará igual, se deprimirán y quizás se suiciden, como venganza ante la muerte, para decidir ellos el momento final. Otros, terceros, se gastarían todos sus ahorros en grandes lujos, en vivir la vida a lo grande, a mandarlo todo a la mierda en un intento de vivir deprisa. Quizá habría un cuarto tipo, los buenos samaritanos, que aprovecharían el resto del tiempo para hacer el bien a los demás, dedicarlo a ayudar todo lo que puedan a sus congéneres, para sentirse mejor. Cadena de favores, y esas cosas. Y el antagónico de este grupo, psicópata enfermizo quizá se dedicaría a delinquir durante toda esa semana, sin reglas, ni leyes, libertinaje, pues no hay miedo a la prisión ni a la perpetua ante la perspectiva de la inminente visita al barquero Caronte.

Me interesan todos estos tipos, pero todos tienen algo en común que les caracteriza profundamente: todos cambiarían de forma más o menos radical sus vidas. El egocéntrico solitario pasaría los últimos momentos con su familia, los fuertes moralistas con grandes ideas para el futuro se desmoronarían como castillos de naipes, sumergidos en los mares de la depresión y, quizá, el suicidio; para los terceros, austeros usureros ahorradores para las generaciones futuras, el shock les produciría la fiebre de vivir ahora deprisa; los no empáticos, egoístas que viven en su nube de algodón se convertirían en misioneros sin fronteras, y los espíritus tranquilos y extremadamente tímidos desatarían la furia sociópata que siempre llevaron dentro.

Sé que estoy generalizando, pero es fácil pensar en todos estos arquetipos. No digo que yo no pertenezca a ninguno de ellos, pero pienso que la respuesta correcta sería seguir haciendo lo que he hecho hasta ahora. Imposible, ¿verdad? ¡Qué utopía! ¡Qué imbecilidad! No me digas que tus últimas horas las “gastarías” haciendo lo que has hecho siempre. Bien, ahora yo les diré que si tanto les trastorna esta respuesta es porque quizá no están viviendo como desearían vivir.

Aquí quería llegar, amigos: todos somos, en mayor o menor medida, dueños de nuestro destino y de nuestra forma de vivir. Desafortunadamente hay gente que no puede, pero la mayoría, al menos en los países desarrollados, tenemos esa inmensa suerte. Puede ELEGIR cómo quiere vivir su vida. Si tus últimos momentos no serían igual que el resto es porque quizás no estás viviendo adecuadamente. Es un cambio de filosofía, amigos: “vive cada momento como si fuera el último”, pero no atropelladamente, entiéndanme. La idea es no dejar todo aquello que deseamos para el final, aprovechar que estamos vivos, valorar lo que tenemos y estar agradecidos por ello.

La idea es decir: voy a visitar a mis padres y a mi familia más a menudo, mejor visitarlos ahora que llevarles flores cuando estén criando malvas. La idea es pensar: voy a cogerme unas vacaciones y visitar la India, un país que siempre quise visitar, por ejemplo. Es cavilar en lo banal que es casi todo en esta vida y que al final, lo único que merece la pena realmente son las personas. Es reflexionar: debería apadrinar un niño, donar dinero a cierta organización, pensar en algo para que los demás puedan disfrutar de la vida con plenitud, como lo hago yo. Finalmente, la idea también es: voy a enfrentarme a los demás, no callarme lo que me sienta mal, ni dejarme pisotear; voy a quererme a mí mismo y a intentar que se me respete igual que yo respeto a los demás. Así seré más feliz.

Por ello, a la pregunta: ¿qué harías si te quedara una semana de vida? creo que la respuesta correcta debería ser: lo mismo que he hecho todos los días hasta el día de hoy…

Espero que hayan reflexionado un poco con estas líneas. También me gustaría recibir sus opiniones al respecto.

Original en: http://luixrodriguezneches.wordpress.com/2008/06/27/te-queda-una-semana-de-vida-%C2%BFque-vas-a-hacer-con-ella/

5 comments March 31, 2009

Conventions for Creation of SQL Queries, Indexes Tables and Fields

  1. Whenever added a new table/field to the database, a comment with his purpose must be included.
  2. Use NOT NULL. Always define columns as NOT NULL unless there is a very good reason not to do so:
    • can save up to a byte per column per row of data
    • nullable columns make indexes, index statistics, and value comparisons more complicated.
  3. Use UNIQUE INDEX. If you have verified that each value for that index will/should not be repeated, then use an unique index (UNIQUE INDEX).
  4. Declaring the data type of a field to the more fixed-value, i. e., if you know the value of an int field is always going to become smaller than 10000, the you should use SMALLINT instead of INT.
  5. Use the smallest possible value for the lengths of the text fields. If you know that a zip code field will always hold not more than 10 characters, then you should use VARCHAR (10) and not VARCHAR (25).
    In cases like encrypted values with the MD5 algorithm, use CHAR (32).
  6. While write reserved keys use always capitalized sustained.

Useful info about the most common MySQL Data Types:

/* Unsigned Numeric Data Types */

TINYINT 0 to 255

SMALLINT 0 to 65535

MEDIUMINT 0 to 16777215

INT 0 to 4294967295

BIGINT 0 to 18446744073709551615

/* Text Data Types */

TEXT 65535 OR 64KB characters

MEDIUMTEXT 16777215 OR 16MB characters

LONGTEXT 4294967295 OR 4GB
characters

4 comments March 31, 2009

General Coding Conventions

Rules

1 Self explanatory code. Make sure your method, class, instance, param and all other self written names in your code are self explanatory.
2 Always include explanatory comments in the code. Make sure every class and method has comments explaining what it does and its purpose, this will make the API documentation easier to understand for other without diving into the code.

/**

  • Get a random prime number starting to search it from a minimal number (default 1)
  • @param minNumber Number Optional minimal number where start the search. Default to 1
  • @return Number Random prime number
  • /

public function findRandomPrimeNumber(minNumber:Number = 1):Number {

}

3 Follow the DRY (Don’t repeat yourself) code philosophy. Make helpers. Make modules. Make plugins. Think in reusable components.

  • If you have a common functionality for two or more classes, please consider to include such functionality in a helper class.
  • If you made a class which have only static functions, like in the case of Utility or Helpers Classes, please consider to use the Singleton Pattern.
4 Avoid too long functions (more than 200 lines). Split to smaller internal functions as needed.

/**

  • /

public function myLongFunction():void {

// Wash clothes
washClothers();

// Now dry them up
dryCycle();

// Notify master that laundry is done
notifyMaster();
}

5 Avoid empty catch blocks. When the exception occurs, nothing happens, and the program fails for unknown reasons.

In general, when a exception occurs, it can be thrown up to the caller, or it can be caught in a catch block. When catching an exception, some options include: inform the user (strongly recommended), log the problem, send an email escribing the problem to an administrator. Deciding what exactly to do seems to depend on the nature of the problem. If there is an actual bug in the program – a defect that needs to be fixed – then one might do all three of the above. In this case, the end user should likely be shown a generic “Sorry, we goofed” message, not a stack trace. It is usually considered bad form to display a stack trace to a non-technical end user, or if exposing a stack trace may be a security risk. If the exception does not represent a bug, then different behavior may be appropriate.
6 Always include { and } on the statements, even if there is a single block code line.
7 Be sure of read all the coding conventions on: Coding Guidelines

Recommendations

1 Only one return on a same function. Do not use returns to break the flow of the code.

  • If you want to know where something is returned, you have to look for the return statement. With multiple return statements you have to go read the complete method and find all the exit points of a method. (isn‘t your method too big?)
  • If you want to log before you exit a method, so with multiple return statements you need to place that logging code before all return statements.

Add comment February 15, 2009

JavaFX v1.0 – Un comienzo prometedor

Tras varias expectativas negativas, la primera versión de JavaFX vio la luz en diciembre del año pasado. Para algunos, esta plataforma llega demasiado tarde, para otros, este es solo el inicio de una plataforma con gran potencial. JavaFX promete permitir desarrollar un aplicación, y sin modificarla, ejecutarla en el computador, en el móvil, en la tv, en el automóvil (”en todas las pantallas de tu vida”). Esto aprovechando la ubicuidad y el musculo que Java ha forjado a lo largo de los años.

Una pregunta común es Por que crear una nueva plataforma para esto?: La principal desventaja de los lenguajes con alto nivel de difusión y longevidad como Java es que esas mismas cualidades exigen una fuerte compatibilidad hacia atrás, lo cual limita a su vez su capacidad de evolucionar. Para comprender la razón de ser de JavaFX, también es relevante considerar los siguientes aspectos: un nuevo y moderno lenguaje, RIAs y flujo programador-diseñador en mente, soporte multimedia, Swing 2.0, alucinantes animaciones al estilo Flash, y todo lo anterior sin salir de Java! JavaFX fue pensado para satisfacer todas esas exigencias; la versión 1.0 ha sido enfocada a dar muy buen soporte al trabajo con animaciones, gráficos y multimedia. En otras palabras, se creó una base muy robusta sobre la cual agregar controles gráficos, frameworks para aplicaciones de gestión, etc. Ahora bien, el primer paso fue solido, de aquí en adelante todo depende de cómo Sun haga evolucionar esta prometedora plataforma.

1 comment February 9, 2009

Can “your” language beat this? – Part 1

Important: This first post is discussed on JavaHispano.org

This series of posts is not intended to demonstrate the superiority of one language over others, the aim is to find the best way to write code snippets that a GUIs developer faces daily. When i said “the best way“, i mean a proper balance between flexibility and readability, which in my view, defines the quality of a language. The idea is that if you knows a language that allows to improve the way of codifying the snippet shown here (surely you knows), then you published that piece of code here, and then we will evaluate the best. As well are welcomes improved versions of the ones I have posted, and of course, comments in general.

The main reason why i choose JavaFX, is frankly because of i think that is the language that gives more agility to work with graphics (at the moment).

This first part aims to show how to bind two objects, in this case, the color of an object is determined by the text of a text field. If the text inside the text field is ‘aeiou’ then the circle will be filled with the green color, otherwise will be filled with the red color.

Note that understanding the processTheText function as the “controller”, so you can notice the complete separation between the view and the logic.

/*
 * DoItBetter1.fx
 *
 */

package doitbetter;

import javafx.scene.control.TextBox;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.Scene;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

var theText = "";

Stage {
    title: "Binding between GUI controls"
    width: 400
    height: 200
    scene: Scene {
        content: HBox {
            spacing: 10
            content: [                
                TextBox{                    
                    text: bind theText with inverse
                }
                Circle{                    
                    radius: 10 centerY: 10
                    fill: bind processTheText(theText)
                }
            ]
        }
    }
}

function processTheText(auxText){
    if(auxText == "aeiou") Color.GREEN else Color.RED
}

2 comments January 15, 2009

JavaFX, why?

It’s not a secret that for a developer is a dream to be able to build an application, and without modify it, run it in the computer, in the cellphone, in the TV, in the car, in all the screens of the life.

However, why to create a new platform for this?: The main disadvantage of the languages with a high level of dissemination and longevity such as Java, is that these same qualities requires a strong backwards compatibility, which in turn limits its ability to evolve.

JavaFX was precisely designed to meet these demands, while provide a new and modern language, RIAs, developer-designer work flow in mind, multimedia, Swing 2.0, amazing Flash’s style animations, and all this without leaving Java! Version 1.0 has been focused on providing a very good support to work with animations, graphics and multimedia. In other words, has been created a very strong base on which to add graphics controls, business applications frameworks, and so on.

For some, JavaFX is coming too late, for others, this is just the beginning of a platform with a great potential. The first step was solid, from now on everything depends on Sun supports to this promising platform.

6 comments January 13, 2009

JavaFX v1.0 – Este es solo el comienzo!

JavaFX 1.0 marca el primer paso de Sun en proveer una novedosa plataforma para crear Aplicaciones Sofisticadas de Internet y distribuirlas en todas las pantallas de tu vida!

JavaFX proporciona la libertad y la flexibilidad de crear RIAs (Rich Internet Aplications) y ejecutarlas en múltiples dispositivos electrónicos, incluyendo: teléfonos móviles, computadores personales, televisores, entre otros.

Principales características de la version 1.0 de JavaFX:

  • Una única plataforma RIA para todas las pantallas: Crear aplicaciones que puedan ser ejecutadas en computadores de escritorio, teléfonos móviles, navegadores de internet, empleando un modelo unificado de desarrollo y de despliegue.
  • Un Lenguaje los más cercano al Natural: JavaFX utiliza un lenguaje declarativo que permite describir fácilmente que debe hacer tu aplicación y como debe lucir.
  • Mercado más amplio: Distribuir RIAs fácilmente a través de miles de millones de dispositivos valiéndose de todo el poder de la Plataforma Java.
  • Facilitar el Flujo de Trabajo entre Diseñador y Programador: Acortar drásticamente el ciclo de producción para el diseño y el desarrollo de las aplicaciones.
  • Potente Entorno de Ejecución: Aproveche la extrema ubicuidad, el poder y la seguridad de la Maquina Virtual Java.
  • Ejecución Independiente del Navegador: Arrastrar y soltar una aplicación JavaFX desde el navegador para desplegar en el escritorio.
  • Compatibilidad con la tecnología Java: Preservar su inversión al permitir el uso de cualquier librería Java desde de una aplicación JavaFX.

La primera versión de JavaFX está realmente destinada a proveer una solida base para todos los avances venideros. Esta versión se ha enfocado en dar muy buen soporte al trabajo con animaciones, gráficos, multimedia, en otras palabras, se está creando una base muy robusta sobre la cual poder agregar Controles Gráficos (formularios, tablas, validadores, etc.), así como Frameworks para facilitar la creación de Aplicaciones de Gestión, Persistencia de Datos, etc. En este contexto se puede hacer una analogía a lo que sucedió con Flash y Flex, Flash es la base, Flex es el Framework para construir RIAs con Flash. JavaFX tiene un mayor musculo que Flash (el gran Universo Java), muy pronto vendrán muchos Componentes y Frameworks para utilizar con JavaFX.

Un aspecto muy importante de JavaFX es que no está restringido por compatibilidades con versiones preexistentes, lo cual da la libertad a sus diseñadores de crear e implementar el mejor diseño posible para ellos, facilitando también la evolución del Lenguaje, aquí la Capacidad de Evolucionar es directamente proporcional a la Libertad.

Como es normal, las primeras versiones tienden a mostrar lo básico y tienen muchos -nice to have- pendientes. Lo que no se puede negar es que JavaFX se ve muy, pero muy prometedor! Una de los aspectos que más me impacta es que la forma de codificar me parece mucho más ágil que en Flex y AS3, no conozco Silverlight aun. Sin mencionar todo el Universo Java comparado con el Mundillo Flash/Flex.

Las próximas versiones de JavaFX saldrán mucho más rápido, en unas cuantas semanas deberíamos tener una siguiente versión de JavaFX, mucho mejor rendimiento de los applets y un mejorado soporte en los entornos de desarrollo, en pocos meses el soporte oficial para Linux, entre otros.

Lo dicho, este es apenas el comienzo!

Una lectura muy recomendada acerca del Pasado, Presente y Futuro del Mundo Desktop en Java: http://www.pushing-pixels.org/?p=922
Enlace al oficial “Acerca de” de JavaFX: http://www.javafx.com/about/overview/

He publicado la noticia en JavaHispano.

Add comment January 8, 2009

SQL to add just the New Indexes (filtering the existing ones)

Quick background

You have several instances of a database, and you adds indexes to improve the performance. Sometimes you does not adds these indexes in all the instances, or for some other reason you need to be sure that all the databases are up to date with the same indexes.

Solution

This document expose a way to extract the indexes from an up to date database (Source Database) and to add just the new Indexes into another database (filtering the already existing ones) by comparing the indexes in each database.

The workflow should be as follows:

  1. In the below SQL scripts, replace ’source_database_name’ and ‘destination_database_name’ with the name of the database in the source and destination database respectively.

  2. Run the query 1 in the Source Database and export the resultset as a CSV file in your local hard drive. By default the 2nd script in the query 2 look for the file ‘C:/Indexes_In_Src_DB.csv’.
  3. Run the query 2 in the Destination Database. This will create some auxiliar databases, which purpose is to store information util to find the not existing indexes.
    Be sure the you’ve named the CSV file as ‘C:/Indexes_In_Src_DB.csv’ or just change that string in the 2nd script in the query 2 by the name you’ve used.
  4. Run the query 3 in the Destination Database, export the resultset as a html file in your local hard drive. Open that html file, copy all the statements and execute those in that same database (Destination Database). This will add the new indexes.
  5. Run the query 4 in the Destination Database. This will delete the auxiliar databases.

Note: To export a resultset in MySQL Query Browser, execute a query, then do right click in the table -> ‘Export Resultset’ -> ‘Export as HTML File’.

Queries

  1. Produce the SQL to Create the Indexes that are in the Source Database

    SELECT
        CONCAT(
            ‘ALTER TABLE `’,
            TABLE_NAME,
            ‘` ‘,
            ‘ADD ‘,
            IF(NON_UNIQUE = 1,
                CASE UPPER(INDEX_TYPE)
                    WHEN ‘FULLTEXT’ THEN ‘FULLTEXT INDEX’
                    WHEN ‘SPATIAL’ THEN ‘SPATIAL INDEX’
                    ELSE CONCAT(‘INDEX `’, INDEX_NAME, ‘` USING ‘, INDEX_TYPE)
                END,
                IF(UPPER(INDEX_NAME) = ‘PRIMARY’,
                    CONCAT(‘PRIMARY KEY USING ‘, INDEX_TYPE),
                    CONCAT(‘UNIQUE INDEX `’, INDEX_NAME, ‘` USING ‘, INDEX_TYPE)
                )
            ),
            ‘(’,
            GROUP_CONCAT(
                DISTINCT
                    CONCAT(‘`’, COLUMN_NAME, ‘`’)
                ORDER BY SEQ_IN_INDEX ASC
                SEPARATOR ‘, ‘
            ),
            ‘);’
         ) AS ‘Show_Add_Indexes’
    FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = ’source_database_name’
    GROUP BY TABLE_NAME, INDEX_NAME
    ORDER BY TABLE_NAME ASC, INDEX_NAME ASC

  2. Create Auxiliar Tables

    /* Temporary Table to store all the Indexes presents in the Source Database */

    DROP TABLE IF EXISTS `indexes_in_src_db`;

    CREATE TABLE `indexes_in_src_db` (
        `TABLE_NAME` VARCHAR(100) NOT NULL,
        `INDEX_NAME` VARCHAR(100) NOT NULL,
        `NON_UNIQUE` TINYINT(1) NOT NULL,
        `INDEX_TYPE` VARCHAR(100) NOT NULL,
        `COLUMNS_NAMES` VARCHAR(230) NOT NULL,
        UNIQUE KEY `table_name_index_name` USING BTREE(`TABLE_NAME`,`INDEX_NAME`),
        UNIQUE KEY `table_name_columns_names` USING BTREE(`TABLE_NAME`,`COLUMNS_NAMES`)
    ) ENGINE=MYISAM DEFAULT CHARSET=utf8;

    /* END */

    /* Load the indexes from the CSV file in the ‘indexes_in_src_db’ table */

    LOAD DATA INFILE ‘C:/Indexes_In_Src_DB.csv’
        INTO TABLE `indexes_in_src_db`
            FIELDS TERMINATED BY ‘,’
            OPTIONALLY ENCLOSED BY ‘"’
            LINES TERMINATED BY rn
            IGNORE 1 LINES;

    /* END */

    /* Temporary Table to store the Indexes presents in the Destination Database */

    DROP TABLE IF EXISTS `indexes_in_dest_db`;

    CREATE TABLE `indexes_in_dest_db` (
        `TABLE_NAME` VARCHAR(100) NOT NULL,
        `INDEX_NAME` VARCHAR(100) NOT NULL,
        `NON_UNIQUE` TINYINT(1) NOT NULL,
        `INDEX_TYPE` VARCHAR(100) NOT NULL,
        `COLUMNS_NAMES` VARCHAR(230) NOT NULL,
        UNIQUE KEY `table_name_index_name` USING BTREE(`TABLE_NAME`,`INDEX_NAME`),
        UNIQUE KEY `table_name_columns_names` USING BTREE(`TABLE_NAME`,`COLUMNS_NAMES`)
    ) ENGINE=MYISAM DEFAULT CHARSET=utf8;

    /* END */

    /* Fill the ‘indexes_in_dest_db’ table with All the Indexes presents in the Destination DB */

    INSERT INTO `indexes_in_dest_db`
    SELECT
       
            TABLE_NAME,
            INDEX_NAME,
            NON_UNIQUE,
            INDEX_TYPE,
            GROUP_CONCAT(
                DISTINCT
                    CONCAT(‘`’, COLUMN_NAME, ‘`’)
                ORDER BY SEQ_IN_INDEX ASC
                SEPARATOR ‘,’
            ) AS COLUMNS_NAMES

    FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = ‘destination_database_name’
    GROUP BY TABLE_NAME, INDEX_NAME;

    /* END */

    /* Temporary Table to store the Indexes presents in Src Database that are not presents in the Destination Database */

    DROP TABLE IF EXISTS `indexes_in_src_db_not_in_dest_db`;

    CREATE TABLE `indexes_in_src_db_not_in_dest_db` (
        `TABLE_NAME` VARCHAR(100) NOT NULL,
        `INDEX_NAME` VARCHAR(100) NOT NULL,
        `NON_UNIQUE` TINYINT(1) NOT NULL,
        `INDEX_TYPE` VARCHAR(100) NOT NULL,
        `COLUMNS_NAMES` VARCHAR(230) NOT NULL,
        UNIQUE KEY `table_name_index_name` USING BTREE(`TABLE_NAME`,`INDEX_NAME`),
        UNIQUE KEY `table_name_columns_names` USING BTREE(`TABLE_NAME`,`COLUMNS_NAMES`)
    ) ENGINE=MYISAM DEFAULT CHARSET=utf8;

    /* Fill the ‘indexes_in_src_db_not_in_dest_db’ table with All the Indexes presents in the Src DB that are not presents in the Dest DB */

    INSERT INTO `indexes_in_src_db_not_in_dest_db`
    SELECT
            SDB.TABLE_NAME,
            SDB.INDEX_NAME,
            SDB.NON_UNIQUE,
            SDB.INDEX_TYPE,
            SDB.COLUMNS_NAMES
    FROM indexes_in_src_db SDB
    WHERE ROW(SDB.TABLE_NAME,SDB.COLUMNS_NAMES) NOT IN(SELECT DDB.TABLE_NAME,DDB.COLUMNS_NAMES FROM indexes_in_dest_db AS DDB)
    GROUP BY SDB.TABLE_NAME, SDB.INDEX_NAME
    ORDER BY SDB.TABLE_NAME ASC, SDB.INDEX_NAME ASC;

    /* END */

  3. Produce the SQL to Add the New Indexes into the Destination Database

    SELECT
        CONCAT(
            ‘ALTER TABLE `’,
            TABLE_NAME,
            ‘` ‘,
            ‘ADD ‘,
            IF(NON_UNIQUE = 1,
                CASE UPPER(INDEX_TYPE)
                    WHEN ‘FULLTEXT’ THEN ‘FULLTEXT INDEX’
                    WHEN ‘SPATIAL’ THEN ‘SPATIAL INDEX’
                    ELSE CONCAT(‘INDEX `’, INDEX_NAME, ‘` USING ‘,INDEX_TYPE)
                END,
                IF(UPPER(INDEX_NAME) = ‘PRIMARY’,
                    CONCAT(‘PRIMARY KEY USING ‘, INDEX_TYPE),
                    CONCAT(‘UNIQUE INDEX `’, INDEX_NAME, ‘` USING ‘,INDEX_TYPE)
                )
            ),
            ‘(’,
            COLUMNS_NAMES,
            ‘);’
         ) AS ‘ADD_Not_Existing_Indexes’
    FROM `indexes_in_src_db_not_in_dest_db`
    GROUP BY TABLE_NAME, INDEX_NAME
    ORDER BY TABLE_NAME ASC, INDEX_NAME ASC;

  4. Drop the auxiliar tables

    DROP TABLE IF EXISTS `indexes_in_src_db`;
    DROP TABLE IF EXISTS `indexes_in_dest_db`;
    DROP TABLE IF EXISTS `indexes_in_src_db_not_in_dest_db`;

1 comment January 5, 2009

Construct SQL to Create Indexes – MySQL

Quick background

You have several instances of a database, and you adds indexes to improve the performance. Sometimes you does not adds these indexes in all the instances, or for some other reason you need to be sure that all the databases have the same indexes (same name, same fields and same type). So, you might be facing a problem, because of MySQL does not provide an automatic way to export the indexes from a database.

Solution

This document expose a way to extract the indexes from a database (Source Database) for use those in another database (Destination Database), using a pure SQL solution.

The workflow should be as follows:

  1. In the below SQL scripts, replace ’source_database_name’ and ‘destination_database_name’ with the name of the database in the source and destination database respectively.

  2. Run the query 1 in the Source Database and export the resultset as an html file in your local hard drive.
  3. Run the query 2 in the Source Database and export the resultset as an html file in your local hard drive.
  4. Run the query 3 in the Destination Database, export the resultset as a html file in your local hard drive.
    Open that html file, copy all the statements and execute those in that same database (Destination Database). This will remove the auto_increment conditions.
  5. Run the query 4 in the Destination Database, export the resultset as a html file in your local hard drive.
    Open that html file, copy all the statements and execute those in that same database (Destination Database). This will remove the indexes.
  6. Open the html file exported in the step 2, copy all the statements and execute those in the Destination Database.
    This will add the auto_increment conditions from the source database.
  7. Open the html file exported in the step 3, copy all the statements and execute those in the Destination Database.
    This will add the indexes from the source database.

Note: To export a resultset in MySQL Query Browser, execute a query, then do right click in the table -> ‘Export Resultset’ -> ‘Export as HTML File’. If you don’t want to use MySQL Query Browser, you can use “INTO OUTFILE” directly in MySQL to export the resultset into a CSV file in your server and then copy it, just something like: SELECT … INTO OUTFILE ‘/result.sql’ FIELDS TERMINATED BY ‘,’ OPTIONALLY ENCLOSED BY ‘”‘ LINES TERMINATED BY ‘rn’ FROM …

Queries

  1. Produce the SQL to Back Up the Creation of the Auto Increment Fields.

    SELECT
        CONCAT(
            ‘ALTER TABLE `’,
            TABLE_NAME,
            ‘` ‘,
            ‘MODIFY COLUMN `’,
            COLUMN_NAME,
            ‘` ‘,
            IF(UPPER(DATA_TYPE) = ‘INT’,
                REPLACE(
                    SUBSTRING_INDEX(
                        UPPER(COLUMN_TYPE),
                        ‘)’,
                        1
                    ),
                    ‘INT’,
                    ‘INTEGER’
                ),
                UPPER(COLUMN_TYPE)
            ),
            ‘) UNSIGNED NOT NULL AUTO_INCREMENT;’
        )
    FROM information_schema.COLUMNS
    WHERE TABLE_SCHEMA = ’source_database_name’ AND
        EXTRA = UPPER(‘AUTO_INCREMENT’)
    ORDER BY TABLE_NAME ASC

  2. Produce the SQL to Back Up the Creation of the Indexes.

    SELECT
        CONCAT(
            ‘ALTER TABLE `’,
            TABLE_NAME,
            ‘` ‘,
            ‘ADD ‘,
            IF(NON_UNIQUE = 1,
                CASE UPPER(INDEX_TYPE)
                    WHEN ‘FULLTEXT’ THEN ‘FULLTEXT INDEX’
                    WHEN ‘SPATIAL’ THEN ‘SPATIAL INDEX’
                    ELSE CONCAT(‘INDEX `’,
                                INDEX_NAME,
                                ‘` USING ‘,
                                INDEX_TYPE
                        )
                END,
                IF(UPPER(INDEX_NAME) = ‘PRIMARY’,
                    CONCAT(‘PRIMARY KEY USING ‘,
                            INDEX_TYPE
                    ),
                    CONCAT(‘UNIQUE INDEX `’,
                            INDEX_NAME,
                            ‘` USING ‘,
                            INDEX_TYPE
                    )
                )
            ),
            ‘(’,
            GROUP_CONCAT(
                DISTINCT
                    CONCAT(‘`’, COLUMN_NAME, ‘`’)
                ORDER BY SEQ_IN_INDEX ASC
                SEPARATOR ‘, ‘
            ),
            ‘);’
         ) AS ‘Show_Add_Indexes’
    FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = ’source_database_name’
    GROUP BY TABLE_NAME, INDEX_NAME
    ORDER BY TABLE_NAME ASC, INDEX_NAME ASC

  3. Produce the SQL to Remove the AUTO_INCREMENT Condition from the Fields.

    SELECT
        CONCAT(
            ‘ALTER TABLE `’,
            TABLE_NAME,
            ‘` ‘,
            ‘MODIFY COLUMN `’,
            COLUMN_NAME,
            ‘` ‘,
            IF(UPPER(DATA_TYPE) = ‘INT’,
                REPLACE(
                    SUBSTRING_INDEX(
                        UPPER(COLUMN_TYPE),
                        ‘)’,
                        1
                    ),
                    ‘INT’,
                    ‘INTEGER’
                ),
                UPPER(COLUMN_TYPE)
            ),
            ‘) UNSIGNED NOT NULL;’
        )
    FROM information_schema.COLUMNS
    WHERE TABLE_SCHEMA = ‘destination_database_name’ AND
        EXTRA = UPPER(‘AUTO_INCREMENT’)
    ORDER BY TABLE_NAME ASC

  4. Produce the SQL to Delete All the Indexes.

    SELECT
        CONCAT(
            ‘ALTER TABLE `’,
            TABLE_NAME,
            ‘` ‘,
            GROUP_CONCAT(
                DISTINCT
                    CONCAT(
                        ‘DROP ‘,
                        IF(UPPER(INDEX_NAME) = ‘PRIMARY’,
                            ‘PRIMARY KEY’,
                            CONCAT(‘INDEX `’, INDEX_NAME, ‘`’)
                        )
                    )
                SEPARATOR ‘, ‘
            ),
            ‘;’
        )
    FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = ‘destination_database_name’
    GROUP BY TABLE_NAME
    ORDER BY TABLE_NAME ASC

2 comments December 2, 2008


RSS Roger Padilla – Thinking in programming

Categories

Recent Posts

Archives

Top Posts

Recent Comments

rogerpadilla on Te queda una semana de vida. ¿…
Arnold on Te queda una semana de vida. ¿…
Tania on Flex Coding Conventions
rogerpadilla on Te queda una semana de vida. ¿…
ravelus on Te queda una semana de vida. ¿…