jueves, 27 de diciembre de 2012

Crear un XML desde un Array en PHP

Hace poco me encontré con la necesidad de generar archivos XML desde PHP. Lo interesante del tema es que el XML debe generarse en el servidor desde algunos parámetros, por eso era necesario incluir un encabezado para que el cliente lo identificara como tal.

Por lo tanto esto se compone de cuatro partes:

1) El encabezado en PHP:

<?php
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');

header('Content-type: text/xml');
?>


2) El array puede ser en cualquier complejidad. Aqui algunos ejemplos:

<?php
$array 
= array(
    
"foo" => "bar",
    
"bar" => "foo",
);
// a partir de PHP 5.4 

$array = [
    
"foo" => "bar",
    
"bar" => "foo",
];
?>

3) La invocación se hace por una función en donde se le pasa el array, indicandole cuál es el nodo del XML en el que se va a encapsular el resto de los datos:

echo arrayToXml($array,'datos');


4) La función que hace el trabajo es la siguiente:

function arrayToXml($array,$lastkey='root')
{
    $buffer.="<".$lastkey.">";
    if (!is_array($array))
    {$buffer.=$array;}
    else
    {
        foreach($array as $key=>$value)
        {
            if (is_array($value))
            {
                if ( is_numeric(key($value)))
                {
                    foreach($value as $bkey=>$bvalue)
                    {
                        $buffer.=arrayToXml($bvalue,$key);
                    }
                }
                else
                {
                    $buffer.=arrayToXml($value,$key);
                }
            }
            else
            {
                    $buffer.=arrayToXml($value,$key);
            }
        }
    }
    $buffer.="</".$lastkey.">";
    return $buffer;
}






5) El resultado que obtenemos es un archivo en XML con la siguiente estructura:

<datos>
   <foo>bar</foo>
   <bar>foo</bar>
</datos>

martes, 18 de diciembre de 2012

Migrar datos y estructuras de SQL Server a MySQL

Recientemente nos encontramos en una disyuntiva dentro de la empresa, en la que nos tocó tomar un giro en la arquitectura de unos de nuestros proyectos principales, que implicaba migrar nuestra plataforma de SQL Server 2005 a MySQL.

Y la primer pregunta que nos surgió fue: "Es posible migrar toda nuestra plataforma e información de SQL Server a MySQL?"... yo ya estaba preparado mentalmente para pasar varias noches con pantuflas peluditas, escuchar rock, y litros de café frente a mi PC haciendo la transición casi manual.

En medio de la lluvia de ideas y de búsquedas me topé con esta herramienta, que realmente me dejó perplejo por su facilidad y gran desarrollo en su interfáz de usuario.

http://www.mysql.com/downloads/workbench/

Es una aplicación desarrollada por los mismos magos de MySQL y pensada para todos aquellos que venimos de otras plataformas de administración de bases de datos.

Validando el HTML y su sintaxis

Durante el desarrollo de cualquier proyecto web o diseño de sitio web, nos enfocamos por tratar de darle gusto al cliente en todo lo que pide, y generalmente omitimos algunas validaciones básicas, entre ellas la más simple de todas y no menos importante: el HTML.

En realidad, la estructura de una página de HTML, ya sea generada por PHP, ASP, .NET, Ruby o cualquier otro lenguaje, debe tener unos lineamientos básicos, pero hoy por hoy, cuando las plataformas se diversifican, las tecnologías cambian tan rápidamente y la premura por entregar el proyecto, hace que nos encontremos en pleno lanzamiento de nuestro proyecto y surge el comentario de algún amigo a última hora: "Oye, no me carga bien en mi Tablet!", ó "Tengo IE 8 y las imágenes se ven corridas para un lado"... y un sin número de detalles más.

Hay muchas librerías que nos ayudan a minimizar este y muchos otros aspectos, pero siempre pasamos por alto lo más obvio... la estructura y la sintaxis del HTML.

No es de angustiarse, pero si de tener un poco más de cuidado. Lo cierto es que aunque estemos trabajando con HTML5, incluimos sintaxis y tags de HTML1, algunas veces por la costumbre, porque no fuimos precavidos en la arquitectura o porque simplemente funcionó y lo dejamos así.

Por eso les traigo esta herramienta, que no importa la versión del HTML con que estemos trabajando (incluyendo HTML5), siempre nos va a orientar en qué estamos fallando:

El enlace es el siguiente:
http://validator.w3.org/

martes, 19 de junio de 2012

Documentando la base de datos

Algunas veces nos encontramos con la necesidad de informar, suministrar, o divulgar la estructura de la base de datos a otras personas. Eso implica poder mostrar el diccionario de datos o la entidad relación de la misma. El otro asunto es que se quiera ver en un formato universal para otros, incluso si no tienen el motor de la base de datos.

Hace poco me encontré con este tema y debía documentar una base de datos para poder ver su entidad relación y diccionario de datos en un diseño de HTML que fuera posible ser visto desde un navegador web.

Durante muchas horas busqué herramientas para lograr esto, incluso estaba considerando hacer una propia, hasta que me encontré una aplicación que por fín cumplía con mis expectativas: DBDesc.

La mecánica es muy sencilla, el aplicativo se conecta a la base de datos y genera un informe en HTML, PDF, RTF o DOC con toda la información de la base de datos, uno puede seleccionar el tipo de plantilla de salida y el tipo de apariencia del informe.  Por si fuera poco, dentro de las configuraciones se puede determinar que tipo de información es la que se necesita en el documento exportado.

Los motores de bases de datos que soporta son:
  • SQL Server 2000, 2005, 2008, 2008 R2
  • Microsoft Desktop Engine 2000 (MSDE) and SQL Server 2005/2008 Express editions
  • MySQL 5.0
  • Oracle 9 and above
  • Microsoft Access 97 and above
  • Firebird
Algunos de los informes generados:
Y adicional, puede generar un mapa de relaciones entre las tablas de la base de datos:




 

sábado, 12 de mayo de 2012

Bases de datos: Usar Identidad o no?

A primera vista, parece que no hay nada especial para considerar antes de usar la propiedad de columna IDENTITY, el mecanismo de la numeración automática de SQL Server. Pero sobre todo en entornos de gran tamaño puede ser vital, primero hay que comprender algunas de las funciones de Identity y algunas de sus limitaciones. En algunos casos, es posible que prefiera utilizar su propio mecanismo de numeración automática. para ayudarnos a decidir sobre el mejor sistema, voy a proporcionar algunos datos sobre la identidad, discutir algunas de sus limitaciones, y mostrar dos alternativas.

Fundamentos de la IDENTIDAD

Aquí hay algunas cosas que usted debe saber sobre la propiedad IDENTITY:
  • Es posible utilizar IDENTIDAD no sólo con los números enteros, pero también con cualquier tipo de datos numéricos que tiene una escala de 0. Esta es una buena cosa, especialmente cuando se necesita para apoyar a los números más grandes que la cantidad de datos que puede contener. El valor entero (INT) tiene una capacidad de 2,147,483,647 registros, y el valor de gran entero (BIGINT) tiene una capacidad de 9,223,372,036,854,775,807 registros.
  • IDENTIDAD, combinado con una restricción PRIMARY KEY o UNIQUE, le permite proporcionar un identificador único de la fila de manera sencilla, sin la necesidad de supervisarlo. SQL Server hace el trabajo por sí solo.
  • A diferencia de la función de secuencia de Oracle, SQL Server no proporciona un mecanismo de secuenciación independiente. En cambio, la secuencia proporcionada por la propiedad IDENTITY se aplica a una sola tabla. Cuando usted necesita un mecanismo de secuenciación que genera números para su uso en las tablas, como diferentes, por ejemplo, con teclas que no deben superponerse a través de tablas, querrá elegir una alternativa a la identidad. Esto es una metodología muy dada en los usuarios de Oracle.
  • La propiedad IDENTITY y la columna a la que está asociado son inseparables, lo que significa que no se puede agregar o quitar de identidad de una columna durante la existencia de los datos. Se puede cambiar esta configuración ya con datos, pero el cambio puede ser muy lento, sobre todo con tablas grandes. Por ejemplo, para dar identidad a una columna existente, puede crear una tabla nueva, copiar los datos de la tabla original, eliminar la tabla original, y luego dar la nueva tabla el mismo nombre. También se puede utilizar un proceso similar para retirar de identidad de una columna existente. En ambos casos, estas actividades requieren que la tabla esté fuera de servicio, tiempo que puede ser muy largo para las tablas grandes o con muchos registros.
  • Cuando se utiliza una instrucción INSERT en una tabla que tiene una columna IDENTITY, el valor de identidad aumenta si el INSERT tiene éxito o fracasa, incluso si se produce un error en una clave principal o CHECK violación de restricción. Si una transacción se revierte, ya sea implícita o explícitamente, el valor de la identidad en esa columna no se revierte, por lo que podría terminar con las lagunas en la secuencia, incluso cuando usted no va a eliminar todas las filas. Esto puede ser un problema cuando se está creando secuencias que no pueden contener espacios, tales como los números de factura.
  • No se puede actualizar vistas particionadas que se basan en tablas que tienen una columna IDENTITY.
  • La sentencia TRUNCATE TABLE restablece la propiedad de IDENTIDAD en la tabla a manipular. Para conservar el contador de identidad, utilice DELETE en lugar de TRUNCATE TABLE, pero tenga en cuenta que DELETE es mucho más lento porque se registra por completo.
El asunto es que una tabla puede existir con y sin IDENTITY, y en ambos casos se puede almacenar registro, editarlos, borrar y actualizar. Pero realmente es el perfil del proyecto el que determina su uso o no.

En qué escenarios es recomendable o no el uso de IDENTITY en una columna.

Es recomendable usar IDENTITY cuando:
  • Nuestra cantidad de registros no dependa de la capacidad del tipo de campo. Es decir, si el proyecto no implica hacer uso de todos y cada uno de los números generados en la secuencia y podemos ser holgados en su contenido.
  • Se manejan proyectos modulares en constante cambio y crecimiento. Esto facilita el entorno de desarrollo y permite la confianza de tener políticas claras con respecto al manejo de la base de datos.
  • Pueden haber cargas transaccionales de consultas complejas.
  • El rendimiento del software se vea afectado.
  • Se requiera de mayor escalabilidad.
No es recomendable usar IDENTITY cuando:
  • El valor del IDENTITY es crítico: numeración de facturas, secuencias de inventarios, comprobantes de pago.
  • La carga transaccional es muy intensa y concurrente desde diferentes escenarios para las operaciones de INSERT y DELETE.
  • No hay control absoluto de la base de datos.

¿Cómo se configura en SQL Server?

Para modificarlo, ingresamos la definición de la tabla y seleccionamos el campo numérico que queremos cambiarle la propiedad:

Por instrucciones de SQL, hay que tener en cuenta que debe hacerlo al momento de crear la tabla:

CREATE TABLE nombredemitabla
    (
    IdPersona int NOT NULL IDENTITY (1, 1)
    )  ON [PRIMARY]
GO

Sin IDENTITY:

CREATE TABLE nombredemitabla
    (
    IdPersona int NOT NULL
    )  ON [PRIMARY]
GO


miércoles, 9 de mayo de 2012

Resturando el IntelliSense en Visual Studio

En algunos escenarios de desarrollo se cuenta con el agradable "IntelliSense", que nos permite ir más rápido que el tiempo que estimamos para un proyecto, y en muchas oportunidades para aprender un poco más del lenguaje.  Pero a veces falla.

Hay dos maneras de solucionar esto, si no funciona la primera, recomiendo de todo corazón la segunda (a veces ni uso la primera):

1a Forma: Configurando el entorno de desarrollo:

Ingresamos en el menú superior por Herramientas -> Opciones y del listado del lado izquierdo seleccionamos "Editor de texto", hay un subitem que se llama "Todos los lenguajes" y éste a su vez una subopción que se llama "General"

Ventana de Opciones del menú de Herramientas Visual Studio 2010

Las casillas de verificación señaladas en la imagen deben estar seleccionadas: "Lista de miembros automática" e "Información de parámetros". Y listo... El IntelliSense volverá a nuestro entorno de desarrollo.

...bueno, cuando cambio de lenguaje de programación, a veces no me funciona... entonces opto por la segunda forma.

2a Forma: Cambiando el entorno de ejecución de la aplicación:

Botón derecho sobre el proyecto, la opción "Página de propiedades", en la lista de la izquierda bucamos "General" y en la lista desplegable de "Versión de .NET Framework de destino" simplemente cambiamos a otro Framework de destino, confirmamos la ventana de advertencia, cerramos nuestro proyecto, lo volvemos a abrir y le ponemos la versión que teníamos originalmente, esto nos pedirá confirmar de nuevo. Cerramos y volvemos a abrir nuestro proyecto. Listo.

En pocas palabras, cambiamos la versión de Framework de destino, y lo volvemos a poner en la versión que necesitamos.  Esto restablece todas las librerías de IntelliSense en el entorno de desarrollo al momento de volver a abrir el Visual Studio.

lunes, 7 de mayo de 2012

Restaurando un archivo .bkf o .bak a una base de datos SQL Server

Esto es tal vez más para mi, pero puede servirle a otros que les haya dado dificultad hacer esta tarea cuando le mandan un archivo .bak o .bkf desde otro servidor y es necesario que lo restauremos en nuestro propio servidor de SQL Server (200, 2005, 2008, 2010 o 2012).  Lo que voy a ilustrar aquí es para 2008, pero es muy equivalente para las otras versiones.

Algunos con entornos de desarrollo, o con simplemente SQL Server Express, necesitan instalar una herramienta visual para administrar sus bases de datos, esta herramienta se denomina "Administrador de tareas de SQL Server", "Microsoft SQL Server Management Studio" o simplemente "SSMSE" (para la versión Express).

Estos etornos gráficos de administración los pueden descargar gratuitamente de Microsoft, y no garantizo la durabilidad de estos enlaces en el tiempo (Microsoft regularmente cambia estas), por lo tanto también pongo la manera en que hice la consulta en Google para llegar a ellos.

Para SQL Server 2005:
Google: "sql server management studio express 2005"
URL: http://www.microsoft.com/downloads/es-es/details.aspx?familyid=c243a5ae-4bd1-4e3d-94b8-5a0f62bf7796

Para SQL Server 2008:
Google: "sql server management studio express 2008"
URL: http://www.microsoft.com/downloads/es-es/details.aspx?FamilyID=08e52ac2-1d62-45f6-9a4a-4b76a8564a2b

Advierto que durante la instalación, se tiene la impresión de que va a instalar de nuevo el servidor de la SQL Server, pero tranquilos, las bases de datos que tengamos en nuestro servidor no se verán afectadas.

Luego en nuestro PC, ingresamos por Inicio -> Todos los programas -> Microsoft SQL Server 2008 y veremos una nueva aplicación que se llama "SQL Server Management Studio"

Ingresamos, nos autenticamos con nuestro servidor y una vez que veamos nuestro listado de bases de datos, buscamos la base de datos que vamos a restaurar con el archivo que nos mandaron o trajimos de otro servidor. Le damos con el botón derecho y seleccionamos las opciones de la imagen:

 En la siguiente ventana seleccionamos que debe ser desde un "dispositivo" la restauración:

Seleccionamos el archivo .bak o .bkf del respaldo y lo agregamos

Una vez cargado el archivo, el sistema detecta los aspectos de la BD a restaurar, pero aquí es donde viene la parte importante. Hay que seleccionar la base de datos que se va a restaurar y luego ir a "Opciones".
En las configuraciones de las opciones, viene siempre por defecto sin ninguna seleción, y además viene con la ruta de los archivos de datos (.mdf) y de registro (.ldf) tal cual como estaban en el servidor de origen.  Si lo dejamos así, entonces no se restaurará y posiblemente no encuentre la ruta donde acomodar los archivos de datos y de registro.  Es por ello que es necesario que le indiquemos que "Sobre escriba la actual base de datos" y además le indicamos donde queremos que queden los archivos de datos y registro en nuestra propia máquina.

Pulsamos "Aceptar" y Voilà!
Nuestra restauración de archivo de respaldo ha terminado y tenemos en nuestra base de datos, todas las tablas y sus respectivos datos, tal cual como estaban al momento en que se realizó el backup o respaldo del servidor.

jueves, 3 de mayo de 2012

¿Cuál es el mejor lenguaje de programación?

Esta es una eterna discusión entre muchos programadores, y siempre he tenido un punto de vista muy claro frente al tema: No hay mejor o peor, simplemente hay: el indicado.

Un buen programador no se define por el lenguaje de programación, se define por dar una solución efectiva y práctica bajo los lineamientos tecnológicos y requerimientos del cliente.

He recorrido muchos lenguajes y plataformas, desde Assembler (Ensamblador), hasta HTML5, pasando por Visual Basic, C++, ASP.NET, PHP, Javascript, y muchos otros, en varias de sus versiones, y puedo hablar tranquilamente que no se trata del lenguaje, sino del proyecto como tal.

Esta discusión es llevada a cabo, en su mayoría por los diseñadores (codificadores, programadores), más que por los analistas (arquitectos); y considero que es debido a su conocimiento actual del lenguaje que ya manejan.

Cuando un novato pregunta a cualquier programador con cuál lenguaje puede comenzar, todos (y hasta el momento no he escuchado al primero que no sea así) siempre le recomiendan el lenguaje con el que tienen mayor experiencia.  De esta manera, cada lenguaje ha ganado su reputación es gracias a la herencia de sus aprendices.


Lo mismo ocurre a nivel de bases de datos, cuál es la mejor y cuál es la peor, todo depende del proyecto, no de la tecnología en sí.

Algunos argumentan la estructuración mental que te brinda trabajar en un lenguaje o en otro, pero con el tiempo la estructuración mental solo se adquiere programando en varios lenguajes. Si se quiere tener estructuración mental a nivel de programación, entonces recomiendo Brainfuck (es mejor que cualquier Sudoku enrazado en Tetris).

Otros aspectos que argumentan esta discusión es el origen del lenguaje, si es código abierto o no, por aquello de contribuir o no a las grandes compañías.  Yo solo tengo un punto de vista para esto: si se quiere ser un programador con vocación de monje, puede seleccionar el lenguaje que prefiera, pero si es alguien mercenario que le trabaja al mejor postor, entonces es el cliente el que selecciona el lenguaje.

La pregunta inicial es tan fácil como difícil de contestar, pero no quiero dar ni la más fácil ni la más difícil, solo la mejor respuesta: "Es cuestión del proyecto".  En cuanto a habilidades de aprendizaje, solo el programador tiene esa respuesta, para orientar un poco al novato, o incluso para que el conocer pueda incursionar, aquí dejo una lista de varios lenguajes de programación con un ejercicio muy sencillo, poner "Hola Mundo" en la pantalla (tomado originalmente de Wikipedia, pero lo traigo porque corregí algunos errores que allí tienen y me he dado cuenta que algunos fanáticos ponen errores en aquellos lenguajes que no gustan):

En ABAP/IV

REPORT HOLAMUNDO.
WRITE '¡Hola, mundo!'.

En ABC

 WRITE "¡Hola mundo!" 

En ActionScript

 trace("¡Hola, mundo!");

En ActionScript 3.0

Opción 1

package
{
 
        import flash.display.Sprite;
 
        public class Main extends Sprite
        {       
 
                public function Main() 
                {
                        trace("¡Hola, Mundo!");
                }
 
        }
}

Opción 2

package
{
        import flash.display.Sprite;
        import flash.text.TextField;
 
        public class Main extends Sprite
        {               
                public function Main() 
                {
                        var txtField = new TextField();
                        txtField.text = "¡Hola, Mundo!";
                        addChild(txtField);
                }
        }
}

En Ada

 with Ada.Text_IO;
 
  procedure Hola_Mundo is
  begin
     Ada.Text_IO.Put("¡Hola, mundo!");
  end Hola_Mundo;

En ALGOL

BEGIN
FILE F (KIND=REMOTE);
EBCDIC ARRAY E [0:12];
REPLACE E BY "HOLA MUNDO!";
WHILE TRUE DO
  BEGIN
  WRITE (F, *, E);
  END;
END.

En AppleScript

 display dialog "Hola, Mundo!" buttons {"OK"} default button {"OK"}

En ASP

<HTML><BODY>
 <%
 Response.Write("Hola Mundo")
 %>
</BODY></HTML>

En AutoIt

MsgBox(0,"","Hola Mundo!")

En Autoplay Media Studio

 Dialog.Message("Noticia", "Hola, Mundo!", MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);

En AWK

#!/bin/awk -f
BEGIN{
  print "¡Hola, mundo!";
}

En Bash

 #!/bin/bash
 echo "Hola mundo"

En Basic

print "Hola Mundo"

En Batch

 @echo off
 echo ¡hola mundo!

En Boo

#!/usr/bin/booish
print "Hola mundo"

En Brainfuck

 ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

En C

#include <stdio.h>
int main()
{
    printf("¡Hola, mundo!\n");
    return 0;
}

En C++

#include <iostream>
using namespace std;
 
int main()
{
  cout << "¡Hola, mundo!" << endl;
  return 0;
}

En C++/CLI

Opción 1

 int main()
 {
    System::Console::WriteLine("Hola, mundo!");
    return 0;
 }

Opción 2

 #include <iostream>
using namespace std;
 void main()
 {
  cout << "Hola mundo\n";
 }

En C#

 using System;
 
 class MainClass
 {
     public static void Main()
     {
         System.Console.WriteLine("¡Hola, mundo!");
     }
 }

En Centura

 Call SalMessageBox('Hola Mundo', 'Saludo', MB_IconExclamation | MB_Ok)

En Clipper

? "Hola Mundo!"

En CLIPS

 (printout t "Hola Mundo" crlf)

En COBOL

IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.
ENVIRONMENT DIVISION.
DATA DIVISION.
PROCEDURE DIVISION.
DISPLAY "Hola mundo".
STOP RUN.

En ColdFusion

<cfset variable="Hola Mundo">
<cfoutput>#variable#</cfoutput>

En CSS (2.0 en adelante)

Sólo para navegadores que cumplan con el estándar CSS 2.0 en adelante.
 body:after {
   content: 'Hola Mundo.';
 }

En D

import std.stdio;
void main()
{
    writefln("Hola mundo");
}

En Delphi

 program PHolaMundo;
 uses
   Dialogs;
 begin
   MessageDlg('Hola Mundo', mtInformation, [mbOK], 0);
 end.

En DIV Games Studio y Fenix GNU

  PROGRAM Hola Mundo;
    PRIVATE fuente1;
    BEGIN 
      fuente1 = load_fnt("help\help.fnt");
      write(fuente1, 160, 100, 4, "Hola Mundo"); 
      LOOP 
        FRAME; 
      END 
    END

En DOS

En sistemas operativos de la familia DOS como MS-DOS o PC-DOS que usan como shell el intérprete de comandos COMMAND. COM o CMD. EXE (OS/2 y Windows de la rama NT) se pueden crear archivos de proceso por lotes con extensiones .BAT y .CMD respectivamente, con el siguiente contenido:
 @echo ¡Hola, Mundo!

En Eiffel

 class HOLA_MUNDO
 create
     make
 feature
     make is
         do
             io.put_string("%nHola mundo%N")
         end
 end  -- HOLA_MUNDO

En ensamblador de PowerPC para Mac OS X

 # hola-ppc.S para Mac OS X
 # gcc -nostdlib hola-ppc.S -o hola-ppc
 .data                    ; datos
 
 hola:
   .ascii    "Hola, mundo!\n"
   hola_len = . - hola
 
 .text                    ; aquí vive el codigo
   .globl start
 
 start:
     li      r0, 4              ; llamada al sistema 4 (sys_write)
     li      r3, 1              ; arg. 1: descriptor de archivo (stdout)
     lis     r4, ha16(hola)     ; arg. 2: puntero a la cadena (parte alta)
     addi    r4, r4,lo16(hola)  ; sumamos la parte baja del mismo
     li      r5, hola_len       ; arg. 3: longitud de la cadena
     sc                         ; llamamos al sistema
     nop
     li        r3, 0            ; el valor que vamos a devolver
     li        r0, 1            ; llamada al sistema sys_exit
     sc
     nop

En ensamblador de PowerPC para GNU/Linux

 # hola-ppc.S para GNU/Linux
 # gcc -nostdlib hola-ppc.S -o hola-ppc
 .data                    # datos
 
 hola:
   .string    "Hola, mundo!\n"
   hola_len = . - hola
 
 .text                    # aqui vive el codigo
   .global _start
 
 _start:
     li      0, 4              # llamada al sistema 4 (sys_write)
     li      3, 1              # arg. 1: descriptor de archivo (stdout)
     lis     4, hola@ha        # arg. 2: puntero a la cadena (parte alta)
     addi    4, 4,hola@l      # sumamos la parte baja del mismo
     li      5, hola_len       # arg. 3: longitud de la cadena
     sc                         # llamamos al sistema
     nop
     li      3, 0            # el valor que vamos a devolver
     li      0, 1            # llamada al sistema sys_exit
     sc
     nop

En ensamblador de x86 para DOS

 .model small
 .stack
 .data
 Cadena1 DB 'Hola Mundo.$'
 .code
 programa:
    mov ax, @data
    mov ds, ax
    mov dx, offset Cadena1
    mov ah, 9
    int 21h
 end programa

En ensamblador de x86 para GNU/Linux

Nasm:
 section .data
 
 msg     db "¡Hola Mundo!", 0Ah
 len     equ     $ - msg  
 
 section .text
 
 global _start
 
 _start:
        mov     eax, 04h
        mov     ebx, 01h
        mov     ecx, msg
        mov     edx, len
        int     80h
        mov     eax, 01h
        mov     ebx, 00h
        int     80h
Gas:
    .section .rodata
    .MSG
        .string "¡Hola Mundo!"
 
    .section .text
    .globl main
main:
    movl $.MSG,(%esp)
    call puts
    movl $1,%eax
    movl $0,%ebx
    int $0x80

En Erlang

-module (hola).
-export([hola_mundo/0]).

hola_mundo() -> io:fwrite("Hola mundo!\n").

En Fortran

 PROGRAM HOLA
 IMPLICIT NONE
   PRINT *, '¡Hola, mundo!'
 END

En Google Go

package main
 
import "fmt"
 
func main() {
        fmt.Println("Hola mundo")
}

En Groovy

 println "Hola Mundo!"

En GWBasic

print "Hola Mundo"

En Haskell

holaMundo :: IO ()
holaMundo = putStrLn "Hola mundo!"

En HTML

 <html>
   <head>
     <title>Hola Mundo</title>
   </head>
   <body>
 
¡Hola Mundo!
   </body>
 </html>

En Icon

procedure main ()
     write ( "Hola Mundo" );
end

En IDL

 print,'Hola Mundo!'

En INTERCAL

PLEASE NOTE Hola mundo en INTERCAL
DO ,1 <- #13
DO ,1 SUB #1 <- #238
DO ,1 SUB #2 <- #28
DO ,1 SUB #3 <- #192
DO ,1 SUB #4 <- #176
DO ,1 SUB #5 <- #82
DO ,1 SUB #6 <- #48
PLEASE DO ,1 SUB #7 <- #78
DO ,1 SUB #8 <- #8
DO ,1 SUB #9 <- #56
DO ,1 SUB #10 <- #80
DO ,1 SUB #11 <- #48
DO ,1 SUB #12 <- #114
DO ,1 SUB #13 <- #52
PLEASE READ OUT ,1
PLEASE GIVE UP

En IHTML

<!iHTML CACHE=TRUE>
<iSET message="Hola Mundo">
  <html>
   <head>
     <title>:message</title>
   </head>
   <body>
      ¡:message
   </body>
 </html>

En Java

public class HolaMundo 
{
  public static void main(String args[])
  {
    System.out.print("Hola Mundo");
  }
}

En JavaScript

 <script type="text/javascript">
   document.write("¡Hola, mundo!");
 </script>

En JCL

//Paso1 EXEC PGM=T9971591
//DDUNO DD IN
%%    Hola mundo

En JSP

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html>
      <%! String hola = "hola mundo"; %>
      <head>
        <title>
          <%= hola %>
        </title>
      </head>
      <body> 
        <%= hola %>
      </body></html>

En Korn Shell

#!usr/bin/ksh
print "Hola Mundo";

En LabVIEW

LVholamundo.png

En Liberty BASIC

 print "¡Hola, mundo!"

En LISP

 (format t "¡Hola, mundo!")

Opción 1

escribe [¡Hola mundo!]

Opción 2

Rotula "Hola GD 90 sl av 50 Rotula "mundo

En LOLCODE

 HAI
 CAN HAS STDIO?
 VISIBLE "HAI WORLD!"
 KTHXBYE

En Lua

Opción 1 (PC)

print("¡Hola, Mundo!\n")

Opción 2 (PSP)

Nombre=color.new(R, G, B)
screen.print(x, y, "Hola, Mundo!",Nombre)

En Malbolge

(=<`:9876Z4321UT.-Q+*)M'&%$H"!~}|Bzy?=|{z]KwZY44Eq0/{mlk**
hKs_dG5[m_BA{?-Y;;Vb'rR5431M}/.zHGwEDCAA@98\6543W10/.R,+O< 

En Maple

"hola mundo";

En Mathematica

Opción 1

hola mundo

Opción 2

Print["hola mundo"]

Opción 3

"hola mundo"

En MATLAB

Opción 1

  disp('Hola Mundo');

Opción 2

  fprintf(1,'Hola Mundo');

En mIRC Scripting

 on 1:start: {
    echo ¡Hola Mundo!
 }

En Modula-2

MODULE Hola;
FROM InOut IMPORT WriteString;
BEGIN
  WriteString ("Hola Mundo");
END Hola.

En Natural

   WRITE "HOLA MUNDO"

En NetLinx

 send_string 0,'Hola Mundo'

En NetREXX

Opción 1: Con REXX clásico

Utilizando la instrucción say que proviene de REXX clásico:
say "Hola Mundo"

Opción 2: Con clases y métodos Java

Utilizando clases y métodos Java:
System.out.println("¡Hola mundo!");

En ObjectPAL

   method holaMundo()
       msgInfo( "", "¡hola mundo!")
   endMethod
   method run(var eventInfo Event)
        msgInfo( "", "¡hola mundo!")
   endMethod

En Object Pascal

    procedure tform1.button1click (sender:tobject);
    //Despues de crear y presionar el botón "button1"
    begin
    showmessage('HOLA MUNDO');
    end;
    end.

En Object REXX

Opción 1: Con REXX clásico

Utilizando los métodos de REXX clásico:
say "Hola Mundo"
call lineout , 'Hola, mundo.'
call charout , 'Hola, mundo.'||eol

Opción 2: Utilizando objetos

Utilizando objetos:
.output~say('Hola, mundo.')
.output~lineout('Hola, mundo.')
.output~charout('Hola, mundo.'||eol) -- eol definido previamente

En Ocaml

   print_endline "Hola mundo";;

En OpenInventor

 #Inventor V2.1 ascii
 Text3 {
   string "Hola mundo"
 }

En Oz

 declare
 {Browse 'Hello World'}

En Pascal

 Program HolaMundo;
 Begin
     Write('¡Hola, Mundo!');
 End.

En Pauscal

  'Pauscal: Lenguaje de programación en español
  Importar "Pauscal.prp"
  Mensaje("¡Hola Mundo!")

En Pawn

 main () {
   print("Hola, mundo!\n");
 }

En Perl

print "Hola, mundo\n";

En Perl v5.10

say 'Hola, mundo';

En PHP

Opción 1

 <?php echo 'Hola Mundo!'; ?>

Opción 2

 <?php print "Hola Mundo!"; ?>

Opción 3

 <?="Hola Mundo!";?>

En PL/1

Hola: procedure options(main);
      put skip list('¡Hola Mundo!');
end Hola;

En PL/SQL

 BEGIN
 DBMS_OUTPUT.Put_Line( 'Hola Mundo' );  
 END;

En Prolog

 write('Hola mundo').

En Python

 print "¡Hola Mundo!"

En Python 3.0

Opción 1

 print('Hola mundo')

Opción 2

 print("Hola mundo")

En QBasic

 PRINT "Hola mundo"

En RapidQ

ShowMessage("Hola, mundo!")

En REXX

say "Hola Mundo"

En Ruby

 puts "Hola Mundo"

En SAPScript

MAIN
P1    Hola Mundo
/

En Scala

object HolaMundo {
 def main(args: Array[String]) =
   println("Hola, mundo")
}

En Scheme

 (let ((HOLA MUNDO
         (lambda ()
           (display "Hola, mundo") 
           (newline))))
    (hola-mundo))
o, simplemente
 (display "Hola, mundo\n")

En Scilab

Opción 1

  disp('Hola, mundo')

Opción 2

  printf('Hola, mundo\n')

En Scratch

HolaMundoScratch.png

En Seed7

$ include "seed7_05.s7i";

const proc: main is func
  begin
    writeln("Hola Mundo");
  end func;

En Smalltalk

 Transcript show: '¡Hola, mundo!'

En SQL

Variante de Oracle:
 SELECT 'HOLA MUNDO'
 FROM DUAL;
Otros SQL (MySQL, Microsoft SQL Server, etc.)
 SELECT 'HOLA MUNDO';
 
 print('HOLA MUNDO')

En Tcl

 puts "Hola mundo"

En Template Toolkit

[% GET "Hola mundo!"; %]

En TiBasic

print "Hola Mundo|"

En TrueBasic

print "Hola Mundo"

En Unlambda

```s``sii`ki
``s``s`ks
    ``s``s`ks``s`k`s`kr
              ``s`k`si``s`k`s`k
                              `d````````````.H.o.l.a.,. .m.u.n.d.o.!
                       k
     k
 `k``s``s`ksk`k.*

En Vala

Opción simple:
void main () {
    print ("Hola mundo\n");
}
Usando orientación a objetos:
class Sample : Object {
        void run () {
                stdout.printf ("Hola mundo\n");
        }
 
        static void main (string[] args) {
                var sample = new Sample ();
                sample.run ();
        }
}

En Visual Basic

Private Sub Form_Load()
   Msgbox "Hola Mundo"
 End Sub

En Visual Basic .NET

 Private Sub Form_Load() Handles Form1.Load
   Messagebox.show("¡Hola, mundo!")
 End Sub
 'modo consola.
 Private Sub Main()
  Console.WriteLine("¡Hola, mundo!")
 End Sub

En Visual FoxPro

 ? "Hola Mundo"

En X3

SubProg HOLAMUNDO()
   Infbox "Hola Mundo"
End

En xBase

? "Hola Mundo"

En XUL

 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
 
 <window
  id="Hola"
  title="Ejemplo: hola mundo"
  orient="vertical"
  persist="screenX screenY width height"
  xmlns= "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <description style='font-size:24pt'>Hola mundo</description>
   <description value='Hola mundo' style='font-size:24pt'/>
   <label value = 'Hola mundo'  style='font-size:24pt'/>
 </window>

lunes, 30 de abril de 2012

Configuraciones universales o parámetros universales

Algunas veces nos encontramos con aplicaciones que requieren configuraciones, y estas, muchas veces, se hacen en un archivo de configuración. Pero luego, nos vamos dando cuenta que el archivo de configuraciones es tan grande, o que hay que darle acceso a varios colaboradores que implica que tengamos muchos detalles de seguridad que contemplar.

Indiferentemente a la tecnología, se puede construir un sistema de configuraciones que sea gestionable a nivel de base de datos y hacer una pantalla administrativa para sus diferentes valores.

¿Qué se puede guardar en un sistema de configuraciones?

Casi de todo: Traducciones, parámetros de configuración, plantillas de html, hojas de estilos css, llaves de acceso a APIs, definición de permisos, etc.

El esquema de la base de datos es la siguiente:

En donde:
  • config_id: Es un autonumérico, llave principal.
  • config_area: Nuestro proyecto puede tener varias áreas, aquí se pueden categorizar las diferentes configuraciones por cada uno de los módulos (usuarios, clientes, chat, agenda, facturas, etc)
  • config_texto: Es necesario que le pongamos un texto indicando de qué se trata la configuración.
  • config_parametro: Este es realmente el parámetro que será llamado desde el código, para poder hacer uso de su valor. Personalmente, acostumbro hacerlo memotécnico para poderlo leer o capturar fácilmente desde el código, por ejemplo: val_chat_permitir_salas_privadas, val_usuario_long_max_login, val_usuario_email_requerido, val_lang_en_register, etc
  • config_valor: Este es el valor que haremos uso en el aplicativo, el que mostraremos, o nos permitirá tener completamente configurado nuestro entorno. Sin importar el tipo de base de datos, es recomendable que sea de gran tamaño el archivo, para que su contenido pueda ser amplio.  en algunos proyectos, incluso aquí ingreso hasta la apariencia completa de la plantilla html del sitio.
Crear la tabla en SQLServer (2000, 2005, 2008)

CREATE TABLE [configuracion]( [config_id] [int] IDENTITY(1,1) NOT NULL, [config_area] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [config_texto] [varchar](1500) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [config_parametro] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [config_valor] [text] COLLATE SQL_Latin1_General_CP1_CI_AS NULL, CONSTRAINT [PK_configuracion] PRIMARY KEY CLUSTERED ( [config_id] ASC ) ) END

Crear la tabla en MySQL
CREATE TABLE IF NOT EXISTS `configuracion` ( `config_id` int(11) NOT NULL AUTO_INCREMENT, `config_area` varchar(50) DEFAULT NULL, `config_texto` varchar(1500) DEFAULT NULL, `config_parametro` varchar(50) DEFAULT NULL, `config_valor` text, PRIMARY KEY (`config_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

Opcional a esto, se puede construir un administrador para estos datos, o se pueden gestionar todas las configuraciones a nivel de base de datos... eso ya depende del alcance que se le quiera dar al sistema de configuraciones universales.

Una sola función para invocar los valores
En VB.NET

Imports System.Data.SqlClient

    Function LN_obtener_configuracion(ByVal parametro As String) As String
        ' por defecto la respuesta de resultado es una cadena en blanco
        Dim rta As String = ""
        'se conecta a la base de datos
        Dim MyConnection As New SqlClient.SqlConnection("Data Source=server_name;Initial Catalog=my_db;Integrated Security=True")
        Dim MyCommand As SqlDataAdapter
        'hace la consulta en la base de datos
        MyCommand = New SqlDataAdapter("Select config_valor from configuracion where config_parametro='" & parametro.ToString() & "'", MyConnection)
        Dim DS As New DataSet
        Try
            MyCommand.Fill(DS, "res")
        Catch ex As Exception
            'aqui se controla cualquier error
        End Try
        'cierra las conexiones
        MyCommand.Dispose()
        MyConnection.Dispose()
        'extrae el valor, solo si hay algun contenido y existe el parámetro
        If DS.Tables("res").Rows.Count > 0 Then
            'Leemos la primera aparición de este valor en la BD, se supone que solo hay un registro con este parámetro
            rta = DS.Tables("res").Rows(0)("config_valor").ToString()
        End If
        'retorna el valor
        Return rta.ToString()
    End Function

En C#.NET
public string LN_obtener_configuracion(string parametro)
{
 // por defecto la respuesta de resultado es una cadena en blanco
 string rta = "";

 //se conecta a la base de datos
 System.Data.SqlClient.SqlConnection MyConnection = new System.Data.SqlClient.SqlConnection("Data Source=server_name;Initial Catalog=my_db;Integrated Security=True");
 SqlDataAdapter MyCommand = default(SqlDataAdapter);

 //hace la consulta en la base de datos
 MyCommand = new SqlDataAdapter("Select config_valor from configuracion where config_parametro='" + parametro.ToString() + "'", MyConnection);
 DataSet DS = new DataSet();
 try {
  MyCommand.Fill(DS, "res");
 } catch (Exception ex) {
  //aqui se controla cualquier error
 }

 //cierra las conexiones
 MyCommand.Dispose();
 MyConnection.Dispose();

 //extrae el valor, solo si hay algun contenido y existe el parámetro
 if (DS.Tables["res"].Rows.Count > 0) {
  //Leemos la primera aparición de este valor en la BD, se supone que solo hay un registro con este parámetro
  rta = DS.Tables["res"].Rows[0]["config_valor"].ToString();
 }
 //retorna el valor
 return rta.ToString();
}

En PHP
function LN_obtener_configuracion($parametro)
{
 $rta = "";
 $con = mysql_connect("localhost","peter","abc123");
 if (!$con) {
   die('Could not connect: ' . mysql_error());
 }
 
 mysql_select_db("my_db", $con);
 $result = mysql_query("Select config_valor from configuracion where config_parametro='" . $parametro . "'");
 while($row = mysql_fetch_array($result)) {
   $rta = $row['config_valor'];
 }
 
 mysql_close($con);
    return $rta;
}

Para su utilización simplemente ponemos en nuestro código:
VB.NET:
Dim txt_mensajebienvenida As String = LN_obtener_configuracion("val_lang_en_hello").ToString()

C#.NET:
string txt_mensajebienvenida = LN_obtener_configuracion("val_lang_en_hello").ToString();

PHP:
$txt_mensajebienvenida = LN_obtener_configuracion('val_lang_en_hello');

Y de esta manera la variable txt_mensajebienvenida tendrá a partir de este momento el valor que le hayamos puesto al parámetro de val_lang_en_hello en la base de datos.


7 razones para no usar Laravel en tu proyecto de PHP

En más de 40 años de experiencia como programador y director de proyectos de programación, he aprendido que cada requerimiento tiene mejores...