lunes, 25 de octubre de 2010

JavaScript: validacion de campos de texto

En internet se puede conseguir un monton de controles para validar cajas de texto.. pero para que buscar en la web si puedo buscar en mi blog.. jejeje.. aqui publico 3 validaciones simples.. solo numeros enteros, numeros con 2 decimales y solo caracteres... copy paste y listo.. a probar



Use el separador de decimales punto "." // usa la funcion js decimales y dosDecimales

Use solo numeros enteros

Use solo caracteres

jueves, 30 de septiembre de 2010

PostgreSQL: Para otorgar privilegios a un usuario

PosgreSQL permite crear provilegios por tabla en la base de datos de manera que un usuario en particular pueda crear consultas SELECT pero no pueda ejecutar el resto UPDATE, DELETE, INSERT.. el problema de esto es que pasa si tienes una BD con muchas tablas, tendrias q generar la sentencia grant por cada tabla GRANT SELECT ON TABLE public.table to u_read; para solucionar esto dejo aqui una consulta que genera todas las sentencias GRANT para cada tabla dentro de la BD

select 'GRANT SELECT ON TABLE '||schemaname||'.'||tablename||' TO u_read;' 
from pg_tables 
where schemaname in ('public') order by schemaname, tablename;


Para ver la Referencia.
Referencia de Postgresql Aqui!

martes, 7 de septiembre de 2010

PostgreSQL: funcion para dividir cadenas a partir de expresiones regulares

la funcion regexp_split_to_table y regexp_split_to_array Dividide una cadena usando expresiones regulares POSIX como el delimitador.

El sigueinte ejemplo divide una cadena de texto utilizando como delimitador 'espacio' para separar las palabras y devolver un arreglo de postgres.
select regexp_split_to_array('hola mundo! que tal!',E'\\s+') as x
y el resultado
{hola,mundo!,que,tal!}

El sigueinte ejemplo divide una cadena de texto utilizando como delimitador 'espacio' para separar las palabras y devolver un recorset que contiene una fila para cada palabra
select regexp_split_to_table('hola mundo como estas',E'\\s+') as x
y el resultado es:
"hola"
"mundo"
"como"
"estas"
puedes cambiar la expresion regular E'\\s+' (que por lo q entiendo son espacios en blanco) por estas otras '[^0-9]+' '[^A-Z]+' '[^A-Z]*' '[^a-z]*' o cualquier otra que utilices, pruebalo y observa los resultados.
Utilidad: imagina que quieres crear usuarios con el primer caracter del nombre y el apellido concatenado a partir de tu tabla de personal de tu sistema administrativo entonces usas esto:
select cedula,nombre,apellido,substring(nombre from 1 for 1) ||
(select regexp_split_to_table(apellido,E'\\s+') as x limit 1) as login,
md5('123456'),1 as status from personal where status = 1 order by cedula
Luego toca verificar la unicidad de los login's de la tabla... y listo...

CSS: Vinculos con texto e imagenes

En muchas ocaciones he tenido que crear vinculos con imagenes/iconos y texto representativos de la accion que realizan, ej. agregar,modificar, eliminar y cada vez q pongo la imagen en la etiqueta <a> la imagen no queda centrada con el texto.. quizas para muchos es una cuestion muy sencilla, pero para mi que no se mucho o nada de CSS es importante.. aqui va el .css para realizar esto:
a
{
  color: #524F46;
  outline: none;
  text-decoration: none;
}

a:hover
{
  text-decoration: underline;
}

a.salir {
    background: transparent url(../images/imgForm/salir.png) no-repeat scroll left center;
    padding: 2px 0 2px 25px;
}

a.listado {
    background: transparent url(../images/imgForm/list.png) no-repeat scroll left center;
    padding: 2px 0 1px 20px;
}

a.agregar {
    background: transparent url(../images/imgForm/add.png) no-repeat scroll left center;
    padding: 2px 0 1px 20px;
}

a.modificar {
    background: transparent url(../images/imgForm/edit.png) no-repeat scroll left center;
    padding: 2px 0 1px 20px;
}

a.eliminar {
    background: transparent url(../images/imgForm/delete.png) no-repeat scroll left center;
    padding: 2px 0 1px 20px;
}

Y en los vinculos donde se implemtentan la hoja de estilos:

Salir

Volver al listado de personal

lunes, 6 de septiembre de 2010

HTML: incrustar los ultimos twits en tu pagina web

Buscando una manera de incrustar los twits mas recientes en una pagina web, me consegui con el siguiente codigo que esta disponible en Twitter y un amigo esta probando para la intranet.. es facil de implementar, solo quizas le falta algo de diseño pero es lo q te da twitter.. aqui va el codigo, solo copialo, cambia la direccion del twitter y listo..
<div  style = "margin-top:0px; margin-bottom:0px; position:relative;left:0px;overflow:hidden;padding-left:0px; 
padding-right:0px; padding-top:0px; padding-bottom:0px;  background-color:;width:100%; ">
<h3 style="overflow:hidden"></h3>
<br/><br/>
<script src="http://widgets.twimg.com/j/2/widget.js"></script>
<script>
new TWTR.Widget({
  version: 2,
  type: 'profile',
  rpp: 10,
  interval: 6000,
  width: 250,
  height: 300,
  theme: {
    shell: {
      background: '#000000',
      color: '#ffffff'
    },
    tweets: {
      background: '#f5edf5',
      color: '#0a0a0a',
      links: '#c73261'
    }
  },
  features: {
    scrollbar: true,
    loop: false,
    live: true,
    hashtags: true,
    timestamp: true,
    avatars: false,
    behavior: 'all'
  }
}).render().setUser('LuisChataing').start();
</script></div>

martes, 31 de agosto de 2010

PostgreSQL: funcion para reemplazar substring

Referencia

La funcion overlay(string placing string from int [for int]) retorna un dato tipo TEXT y reeplaza parte de una cadena...

ejemplo de la funcion:
select overlay('Txxxxas' placing 'hom' from 2 for 4)

En la funcion overlay indicas el inicio de la cadena a reemplazar y la cantidad de caracteres q eliminaras de la cadena original, no importa si la subcadena nueva contenga la misma cantidad de caracteres. en el ejemplo se elimina desde el caracter 2, 4 caracteres 'xxxx' y se reeplaza con 'hom' 3 caracteres.. y el resultado es: Thomas

Tambien existe la funcion replace(string text, from text, to text) que reemplaza las ocurrencias de una cadena en otra por otra cadena

ejemplo de la funcion:

select replace('abcdefabcdef', 'cd', 'XYZ')
y el resultado es 'abXYZefabXYZef'

lunes, 30 de agosto de 2010

SVN: eliminar los archivos .svn el proyecto

Este comando lo paso un amigo hace un tiempo... el comando busca los archivos .svn y los elimina.. muy util para subir proyectos al SVN que antes estaban en otro SVN, claro, suponiendo q ya no eliminaste los archivos .svn desde el IDE (ej. eclipse)

Debes entrar en la carpeta y luego ejecutar el comando y listo!

$ cd /var/www/proy
$ find . -name .svn -print0 | xargs -0 rm -rf

Comando Linux: Diff - para comparar archivos -

Es invocado desde la línea de comando con los nombres de dos archivos: diff original new. El resultado del comando representa los cambios requeridos para hacer que el archivo original se convierta en el nuevo archivo.
Si original y nuevo son directorios, entonces diff se ejecutará sobre cada archivo que exista en ambos directorios. Una opción, -r, hará que cualesquiera subdirectorios emparejados comparen archivos entre directorios.


$ diff original.txt nuevo.txt 
 y tambien puedes utilizar

$ diff -e original.txt nuevo.txt

domingo, 29 de agosto de 2010

PostgreSQL: Funcion que convierte un numero a texto

La siguiente funcion esta escrita en plpgsql y retorna un cadena de texto correspondiente a un numero que se pasa por parametro, la funcion devuelve hasta un maximo de 999999999,99
Esta funcion la saque de un foro hace un tiempo ya, la tenia en alguna BD de prueba y para no perderla... pues la coloco aqui..

-- DROP FUNCTION f_convnl(numeric);

CREATE OR REPLACE FUNCTION f_convnl(num numeric)
  RETURNS character varying AS
$BODY$
-- Función que devuelve la cadena de texto en castellano que corresponde a un número.
-- Parámetros: número con 2 decimales, máximo 999999999,99.

 
DECLARE 
 d VARCHAR[];
 f VARCHAR[];

 g VARCHAR[];
 numt VARCHAR;
 txt VARCHAR;

 a INTEGER;
 a1 INTEGER;
 a2 INTEGER;
 n INTEGER;

 p INTEGER;
 negativo BOOLEAN;
BEGIN
 -- Máximo 999.999.999,99

 IF num > 999999999.99 THEN
  RETURN '---';

 END IF;
 txt = '';
 d = ARRAY[' un',' dos',' tres',' cuatro',' cinco',' seis',' siete',' ocho',' nueve',' diez',' once',' doce',' trece',' catorce',' quince',

  ' dieciseis',' diecisiete',' dieciocho',' diecinueve',' veinte',' veintiun',' veintidos', ' veintitres', ' veinticuatro', ' veinticinco',

  ' veintiseis',' veintisiete',' veintiocho',' veintinueve'];

 f = ARRAY ['','',' treinta',' cuarenta',' cincuenta',' sesenta',' setenta',' ochenta', ' noventa'];

 g= ARRAY [' ciento',' doscientos',' trescientos',' cuatrocientos',' quinientos',' seiscientos',' setecientos',' ochocientos',' novecientos'];

 numt = LPAD((num::numeric(12,2))::text,12,'0');

 IF strpos(numt,'-') > 0 THEN

    negativo = TRUE;
 ELSE
    negativo = FALSE;

 END IF;
 numt = TRANSLATE(numt,'-','0');

 numt = TRANSLATE(numt,'.,','');

 -- Trato 4 grupos: millones, miles, unidades y decimales
 p = 1;
 FOR i IN 1..4 LOOP

  IF i < 4 THEN
   n = substring(numt::text FROM p FOR 3);

  ELSE
   n = substring(numt::text FROM p FOR 2);

  END IF;
  p = p + 3;
  IF i = 4 THEN

   IF txt = '' THEN
    txt = ' cero';

   END IF;
   IF n > 0 THEN
   -- Empieza con los decimales

    txt = txt || ' con';
   END IF;

  END IF;
  -- Centenas 
  IF n > 99 THEN

   a = substring(n::text FROM 1 FOR 1);

   a1 = substring(n::text FROM 2 FOR 2);

   IF a = 1 THEN
    IF a1 = 0 THEN

     txt = txt || ' cien';
    ELSE
     txt = txt || ' ciento';

    END IF;
   ELSE
    txt = txt || g[a];

   END IF;
  ELSE
   a1 = n;
  END IF;

  -- Decenas
  a = a1;
  IF a > 0 THEN

   IF a < 30 THEN
    IF a = 21 AND (i = 3 OR i = 4) THEN

     txt = txt || ' veintiuno';
    ELSIF n = 1 AND i = 2 THEN

     txt = txt; 
    ELSIF a = 1 AND (i = 3 OR i = 4)THEN

     txt = txt || ' uno';
    ELSE
     txt = txt || d[a];

    END IF;
   ELSE
    a1 = substring(a::text FROM 1 FOR 1);

    a2 = substring(a::text FROM 2 FOR 1);

    IF a2 = 1 AND (i = 3 OR i = 4) THEN

      txt = txt || f[a1] || ' y' || ' uno';

    ELSE
     IF a2 <> 0 THEN
      txt = txt || f[a1] || ' y' || d[a2];

     ELSE
      txt = txt || f[a1];
     END IF;

    END IF;
   END IF;
  END IF;

  IF n > 0 THEN
   IF i = 1 THEN

    IF n = 1 THEN
     txt = txt || ' millón';

    ELSE
     txt = txt || ' millones';
    END IF;

   ELSIF i = 2 THEN
    txt = txt || ' mil';

   END IF;  
  END IF;
 END LOOP;

 txt = LTRIM(txt);
 IF negativo = TRUE THEN

    txt= '-' || txt;
 END IF;
    RETURN txt;

END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
ALTER FUNCTION f_convnl(numeric) OWNER TO u_test;

viernes, 27 de agosto de 2010

PostgreSQL: Lenguajes procedimentales

Los lenguajes procedimentales son utilizados para realizar funciones complejas e base de datos, Postgres al igual q SQLServer, Oracle y otros posee lenguajes procedimentales, a mi parecer mucho mejor q SQLServer por q no solo tienes que diseñar tus funciones con el lenguaje por defecto, si no q tambien los creas con diferentes lenguajes:
plruby , pljava , plproxy , plperl, C y creo q otros....

El nativo de postgres plpgsql.

Para instalar leguajes procedimentales en postgres:

plpgsql es el lenguaje procedimental de postgres por defecto, para instalarlo se ejecuta el siguiente comando como el usuario postgres:
# su - postgres
$ psql data_db
data_db=# CREATE TRUSTED PROCEDURAL LANGUAGE plpgsql;

para otro tipo de lenguajes como C o Perl debes buscar el paquete e instalarlo como el usuario root:
# aptitude search plperl
# aptitude install postgresql-plperl-8.3

cambias al usuario postgres y creas el lenguaje
# su - postgres
$ psql data_db
data_db=# CREATE TRUSTED PROCEDURAL LANGUAGE plperl;

Listo!

lunes, 23 de agosto de 2010

PostgreSQL: DBlink, conexion entre bases de datos postgres

DBlink consta de un conjunto de funciones diseñadas para realizar conexiones entre bases de datos Postgres, en el mismo server o en otros.. lo que se necesita es instalar DBlink en el servidor que hace la peticion..
Para implementar esto debes instalar el paquete contrib de la version que usas de postres
# aptitude install postgresql-contrib-8.3
el contrib de postgres provee una serie de funciones muy utiles para desarrolladores y administradores.
Para instalar la funcion en tu BD debes ser el usuario postgres y por lineas de comando:
$ cd /usr/share/postgresql/8.3/contrib
$ psql test_db u_test -h localhost < dblink.sql
Te conectas a la BD que tiene instalado el DBlink y realizas la consulta
$ psql test_db u_test -h localhost
La idea es trear datos de la BD my_db que esta en el servidor 191.168.50.90 y mostrarlos en la conexion establecida en test_db en localhost
test_db=# select * from
dblink ('dbname=my_db hostaddr=191.168.50.90 user=u_test password=123456 port=5432',
'select id,descripcion from tabla')  as t1(id int4,descripcion text); 

Listo!

miércoles, 4 de agosto de 2010

PostgreSQL: Postgresql-autodoc

postgresql_autodoc:
varios tipos de archivo a partir de una bd postgresql para la documentacion de de la base de datos..
archivos que genera:
    .dia .htm .xml .dot (a partir de este archivo se genera un .png del diagrama) y otros....

Instalacion
# aptitude install postgresql-autodoc
# aptitude install dia
# aptitude install GraphViz

Opciones de uso:
$ postgresql_autodoc--help

Para generar los documentos:
$ postgresql_autodoc -d Nomb_BD -f /ruta_destino/Nombre_BD -h localhost -u usuario_db --password=pass_db

    -d = base de datos
    -f = archivo destino y el prefijo de los archivos generados
              se generan archivos como:
                           /ruta_destino/Nombre_BD.dia
                           /ruta_destino/Nombre_BD.html
                           .....
               ...
    -h = host de la bd
    -u = usuario
    --password= =password de bd

Luego para generar una imagen .png apartir del documento .dot generado con postgresql_autodoc ejecutamos el siguiente comando
$ dot -Tpng -o /ruta_destino/output.png /ruta_destino/Nombre_BD.dot

PHP: Problemas de apache2 al interpretar PHP5

En algunas oportunidades me he visto en la necesidad de configurar ambientes de desarrollo en diferentes maquinas.. algunas veces todo va muy bien otras no tanto.. en particular al instalar apache2 y php5 en algunas ocaciones (no se en realidad el por que de esto) apache no interpreta en php y el navegador lanza una ventanita diciendo algo asi como descargar archivo.php.. para solucionar esto edita el archivo apache2.conf:

# vim /etc/apache2/apache2.conf
Al final del archivo colocas los siguiente:
LoadModule php5_module modules/libphp5.so

AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

Luego solo reiniciamos el servicio

# /etc/init.d/apache2 restart

miércoles, 28 de julio de 2010

PHP: APC acelerador de php

Codigos PHP (normales o con frameworks como Symfony) requieren que tengas instalado un acelerador de PHP usando de manera mucho mas eficiente el cache.. Aqui un buen tip para instalar el APC

Instalacion de alternate php cache(acelerador de php)
# aptitude install apache2-threaded-dev php5-dev libmagic-dev
# pecl install apc

para versiones recientes de Ubuntu

# aptitude install php-apc

modificamos el php.ini

# vim /etc/php5/apache2/php.ini

en la seccion destinada para las extenciones agregamos
extension=apc.so
    [APC]
    apc.enabled=1
    apc.shm_segments = 1
    apc.shm_size = 64
    apc.max_file_size = 10M
    apc.stat = 1

# /etc/init.d/apache2 restart

Listo.. busca en la maquina apc.php descomprimelo y copialo en /var/www/
ejecutalo en el navegador y observa su comportamiento

# updatedb
# locate apc.php

en mi caso /usr/share/doc/php-apc/apc.php.gz

Listo!

martes, 27 de julio de 2010

MySQL: otorgar permisos a la BD a otros hosts

Para dar permisos a otros host para el acceso a las BD en general desde MySQL solo debes ingresar por consola y ejecutar las siguientes lineas:

$ mysql -u root -p
mysql> GRANT ALL ON *.* TO 'root'@'191.168.50.72' IDENTIFIED BY '123456' with grant option;
Si luego de realizar eso aun se genera el error: Access denied for user 'root'@'' (using password: YES) Esto indica que existe un problema con DNS. Para arreglarlo, es necesario ejecutar:
$ mysqladmin -p flush-hosts
para reestablecer la cache interna de DNS. Y listo!

lunes, 26 de julio de 2010

PostgreSQL: crosstab - Filas a columnas en una consulta SQL-

Bien.. hace unos dias me preguntaron como se crea una consulta para transformar filas a columnas, muy usado para generar reportes en tus codigos PHP, pues bien, en SQL server aparentemente debes usar procedimientos almacenados, en Oracle 11g existe una funcion PIVOT, pero investigando por ahi consegui esta informacion en la misma pagina de postgres... Ver.
Normalmente para evitar programar funciones o procedimientos almacenados uno crea codigo php medianamente complejo para armar las consultas y cambiar las filas q contienen resultados o datos de filas a columnas agrupando valores para conseguir un reporte que se entienda aqui voy a explicar como se hace en Postgres 8.3 y 8.4 utilizando las librerias contrib

Primero, debes tener instalado en contrib en la maquina
# aptitude install postgresql-contrib-8.3


el contrib de postgres provee una serie de funciones muy utiles para desarrolladores y administradores (Ej. dblink) asi como tambien la funcion crosstab

para instalar la funcion en tu BD debes ser el usuario postgres en la maquina y por lineas de comando
$ cd /usr/share/postgresql/8.3/contrib
$ psql test < tablefunc.sql


Y listo.. tu bd test tiene habilitada la funcion.. si necesitas q tus otras BD tengan la funcion cargada debes hacer el procedimiento por cada BD.. ahora, si necesitas que todas tus futuras bases de datos vengan con la funcion precargada al momento de crearlas debes hacer esto:

$ cd /usr/share/postgresql/8.3/contrib
$ psql template1 < tablefunc.sql


bien, ya tenemos las funciones cargadas, pero ¿Como la usamos?...
veamos un ejemplo:
creamos una tabla de prueba con datos
CREATE TABLE ct(id SERIAL, rowid TEXT, attribute TEXT, value TEXT);
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att1','val1');
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att2','val2');
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att3','val3');
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att4','val4');
INSERT INTO ct(rowid, attribute, value) VALUES('test2','att1','val5');
INSERT INTO ct(rowid, attribute, value) VALUES('test2','att2','val6');
INSERT INTO ct(rowid, attribute, value) VALUES('test2','att3','val7');
INSERT INTO ct(rowid, attribute, value) VALUES('test2','att4','val8');


Visualizamos los datos

select * from ct

1;"test1";"att1";"val1"
2;"test1";"att2";"val2"
3;"test1";"att3";"val3"
4;"test1";"att4";"val4"
5;"test2";"att1";"val5"
6;"test2";"att2";"val6"
7;"test2";"att3";"val7"
8;"test2";"att4";"val8"



y ahora a ver la funcion en accion: queremos ver test1 y test2 con todos sus valores en la misma fila:
SELECT *
FROM crosstab(
'select rowid, attribute, value
from ct
order by rowid,attribute')
AS ct(row_name text, category_1 text, category_2 text, category_3 text, category_4 text);

"test1";"val1";"val2";"val3";"val4"
"test2";"val5";"val6";"val7";"val8"

Y listo..

jueves, 22 de julio de 2010

Cheat Sheet: Hoja de trucos

Aqui un vinculo que un pana me paso..

Multiples hojas llenas de tips de diversos topicos..

CCS, HTML, Photoshop, PHP

Muy util...
Clik aqui

martes, 20 de julio de 2010

SVN: configuración

Configuración de SVN

# apt-get install subversion
# apt-get install libapache2-svn
# mkdir -p /var/local/repositorio
# svnadmin create /var/local/repositorio/
# chown -R www-data:www-data /var/local/repositorio/
# cd /etc/apache2/mods-available/
# vim dav_svn.conf

<Location /repositorio>
DAV svn
SVNPath /var/local/repositorio
AuthType Basic
AuthName "Subversion repository"
### fichero de passwords
AuthUserFile /etc/subversion/passwd
### permito las opciones GET PROPFIND OPTIONS REPORT a usuarios anonimos
<LimitExcept GET PROPFIND OPTIONS REPORT>
### pero requiero autentificación para el resto de operaciones
Require valid-user
</LimitExcept>
</Location>

# /etc/init.d/apache2 restart
# htpasswd -c /etc/subversion/passwd rramos
# cd /var/local/conf
# vim passwd

viernes, 16 de julio de 2010

PostgreSQL: Calcular la edad y obtener el grupo etario

Esta consulta es util si lo que se desa obtener es la edad de las personas registradas, ademas obtener el grupo etario al cual pertenecen.. Una consulta muy util si se desea realizar estadisticas por grupo etario..

select count(*),
/*substring(age(now(),p.f_nacimiento)::text from 1 for 2)::int as edad, --Descomentar si deseas la edad de las personas*/
case
when substring(age(now(),p.f_nacimiento)::text from 1 for 2)::int between 0 and 12
then '1-. INFANTE (0-12)'
when substring(age(now(),p.f_nacimiento)::text from 1 for 2)::int between 13 and 17
then '2-. ADOLESCENTE (13-17)'
when substring(age(now(),p.f_nacimiento)::text from 1 for 2)::int between 18 and 28
then '3-. JOVEN (18-28)'
when substring(age(now(),p.f_nacimiento)::text from 1 for 2)::int between 29 and 35
then '4-. ADULTO JOVEN (29-35)'
when substring(age(now(),p.f_nacimiento)::text from 1 for 2)::int between 36 and 59
then '5-. ADULTO (36-59)'
when substring(age(now(),p.f_nacimiento)::text from 1 for 2)::int >= 60
then '6-. ADULTO MAYOR (60 o mas)'
end AS grupo_etario
from persona p
group by grupo_etario /*,edad --Descomentar si deseas la edad de las personas*/
order by grupo_etario

jueves, 15 de julio de 2010

Probando SyntaxHighlighter

Despues de algunos intentos al fin me funciono.. la tactica para publicar en blogger es esta.. los script de SyntaxHighlighter debes colocarlos en la pagina del blog no en el articulo(tonto yo q no sabia).. en Diseño -> Edicion de HTML
Dentro de la etiqueta <head> colocas los script q vas a usar para publicar tu codigo.. en mi caso lo siguinte:



tu articulo con el codigo fuente va entre los tags <pre class="brush: js;"> .... </pre>

Y al poner tu codigo de ejemplo se ve asi..

function public HolaMundo
{
return 'Hola!!';
}