miércoles, diciembre 16, 2009

Buscar y Reemplazar texto desde la cónsola

Buscar y Reemplazar texto desde la cónsola en varios archivos y sus subdirectorios

http://www.guatewireless.org/buscar-y-reemplazar-texto-en-todos-los-archivos-dentro-de-un-directorio-y-todos-los-subdirectorios/

find ./ "*.php" | xargs perl -pi -e 's/user=yoyoyoyo/user=tambien/g'

martes, octubre 27, 2009

Sabiduría para programar

Recientemente leí en el histórica de la lista de postgresql, en palabras de Alvaro Herrera, algo así como:
No le digas como lo va a hacer, dile qué es lo que tiene que hacer
. Palabras que hoy en día me sonaron, por mucho, llenas de sabiduría... ¿a qué se refería? era parte de una respuesta a una programación del lado de la Base de Datos... mejorar la programación, el rendimiento del motor, etc...

Haré el intento de conseguir las palabras exactas...

viernes, octubre 16, 2009

Insertar varios registros sí no existe

Bueno... es posible que esta idea este extraña, pero así es como lo tenemos.

Nuestro código político está más o menos así:
\d region
Tabla «public.region»
Columna | Tipo | Modificadores
---------+-----------------------+---------------
reg_001 | character varying(2) | not null
reg_002 | character varying(35) | not null
Índices:
«region_pkey» PRIMARY KEY, btree (reg_001)

\d estado
Tabla «public.estado»
Columna | Tipo | Modificadores
---------+-----------------------+---------------
reg_001 | character varying(2) | not null
est_001 | character varying(2) | not null
est_002 | character varying(35) | not null
Índices:
«estado_pkey» PRIMARY KEY, btree (est_001)
«estado_ukey» UNIQUE, btree (reg_001, est_001)
Restricciones de llave foránea:
«estado_fkey» FOREIGN KEY (reg_001) REFERENCES region(reg_001) ON UPDATE CASCADE ON DELETE RESTRICT

\d municipio
Tabla «public.municipio»
Columna | Tipo | Modificadores
---------+-----------------------+---------------
reg_001 | character varying(2) | not null
est_001 | character varying(2) | not null
mun_001 | character varying(2) | not null
mun_002 | character varying(35) | not null
Índices:
«municipio_ukey» UNIQUE, btree (reg_001, est_001, mun_001)
Restricciones de llave foránea:
«municipio_fkey» FOREIGN KEY (est_001) REFERENCES estado(est_001) ON UPDATE CASCADE ON DELETE RESTRICT

\d parroquia
Tabla «public.parroquia»
Columna | Tipo | Modificadores
---------+-----------------------+---------------
reg_001 | character varying(2) | not null
est_001 | character varying(2) | not null
mun_001 | character varying(2) | not null
par_001 | character varying(2) | not null
par_002 | character varying(35) | not null
Índices:
«parroquia_ukey» UNIQUE, btree (reg_001, est_001, mun_001, par_001)

\d centro_poblado
Tabla «public.centro_poblado»
Columna | Tipo | Modificadores
---------+-----------------------+-------------------------------------------------------------
reg_001 | character varying(2) | not null
est_001 | character varying(2) | not null
mun_001 | character varying(2) | not null
par_001 | character varying(2) | not null
cpo_001 | character varying(3) | not null
cpo_002 | character varying(50) | not null
id | integer | not null default nextval('centro_poblado_id_seq'::regclass)

Y para el registro de datos, existe la posibilidad de que el detalle no llegue sino hasta la parroquia, por ejemplo, por lo que habría que seleccionar un Centro Poblado del tipo 'No Aplica', pero, un 'No Aplica' por cada parroquia existente, son como... muchos! al menos para insertarlos manualmente y uno por uno, así que decidí estudiar un poquito y ver cómo lo hacía vía plpgsql, he aquí el resultado:
CREATE OR REPLACE FUNCTION leer(out a varchar) RETURNS SETOF varchar LANGUAGE plpgsql AS $$
DECLARE
r record;
p varchar := '01';
BEGIN
-- recorrer la tabla tantas veces como parroquias existan
FOR r IN SELECT par_001 FROM centro_poblado GROUP BY par_001 LOOP
-- recorrer la tabla tantas veces como parroquias existan y centros poblados con código igual a '000' existan
FOR r IN SELECT COUNT(*) AS cuenta FROM centro_poblado WHERE par_001 = p AND cpo_001 = '000' LOOP
-- inicializo 'a'
a = r.cuenta;
-- sí a leido como entero, es igual a cero, es porque no existe un centro poblado con código igual a '000'
IF (a::int = 0) THEN
-- insertar el registro
INSERT INTO centro_poblado (reg_001, est_001, mun_001, par_001, cpo_001, cpo_002) VALUES ('06', '14', '01', p, '000', 'No Aplica');
END IF;
-- incremento para pasar a la siguiente parroquia
p := '0'|| p::int + 1;
-- paso a la siguiente parroquia
RETURN next;
END LOOP;
END LOOP;
END;
$$;

Seguro, alguien consigue otra forma de hacerlo mejor, pero al menos sirve... También es posible ir lanzando algunas notificaciones para saber por dónde y cómo va, tal como RAISE NOTICE ' Parroquia tiene %',p; pero es a gusto de cada quien...

Listo! yo mismo lo hice de otra forma:

--
-- funcion para insertar no aplica para parroquias
--
CREATE OR REPLACE FUNCTION insertar_no_aplica_centro_poblado(e varchar, out a varchar) RETURNS SETOF varchar LANGUAGE plpgsql AS $$
DECLARE
l record;
r record;
p record;
BEGIN
create temp table audit_tmp (usuario integer, ip inet, ocurrencia timestamp default now());
-- listar todas las parroquias y municipios agrupadas
FOR l IN SELECT mun_001 FROM centro_poblado WHERE est_001 = e GROUP BY mun_001 ORDER BY mun_001 LOOP
FOR r IN SELECT par_001 FROM centro_poblado WHERE est_001 = e AND mun_001 = l.mun_001 GROUP BY par_001 ORDER BY par_001 LOOP
FOR p IN SELECT cpo_001 FROM centro_poblado WHERE est_001 = e AND mun_001 = l.mun_001 AND par_001 = r.par_001 GROUP BY cpo_001 ORDER BY cpo_001 LOOP
IF (p.cpo_001 = '000') THEN
RAISE NOTICE 'No Aplica para : %', r.par_001;
EXIT;
ELSE
insert into audit_tmp values (1, '127.0.0.1');
RAISE NOTICE 'Insertando para la parroquia : %', r.par_001;
INSERT INTO centro_poblado (reg_001, est_001, mun_001, par_001, cpo_001, cpo_002) VALUES ('06', e, l.mun_001, r.par_001, '000', 'No Aplica');
EXIT;
END IF;
END LOOP;
END LOOP;
END LOOP;
END;
$$;

Ya ven, es otra forma...

miércoles, octubre 14, 2009

Eliminando registros duplicados, desde SQL

Zas! Por un error de programación, de repente aparecieron un montón de registros duplicados, y cuando digo un montón, son un montón!!!

y ahora? pues, a pensar con cabeza fría... cuáles son las opciones?
  • borrar todos los duplicados a través del mismo sistema
  • pensar en un script en cualquier lenguaje que haga todo de un sólo halón
Por razones de seguridad de los datos, me inclino por la segunda opción... lo primero que pensé es en cómo se podía hacer con SQL

La tabla:
\d centro_poblado
Tabla «public.centro_poblado»
Columna | Tipo | Modificadores
---------+-----------------------+-------------------------------------------------------------
reg_001 | character varying(2) | not null
est_001 | character varying(2) | not null
mun_001 | character varying(2) | not null
par_001 | character varying(2) | not null
cpo_001 | character varying(3) | not null
cpo_002 | character varying(50) | not null
id | integer | not null default nextval('centro_poblado_id_seq'::regclass)

Como la tabla tiene un id de tipo serial, eso ayuda.

Verficiar cuáles son los registros repetidos:
SELECT COUNT(*), reg_001, est_001, mun_001, par_001 FROM centro_poblado GROUP BY cpo_002, reg_001, est_001, mun_001, par_001 ORDER BY reg_001, est_001, mun_001, par_001;

Verificar los registros repetidos:
SELECT * FROM centro_poblado WHERE reg_001 = '06' AND est_001 = '14' AND mun_001 = '01' AND par_001 = '05';

Contar los registros repetidos, en detalle:
SELECT count(*) FROM centro_poblado WHERE reg_001 = '06' AND est_001 = '14' AND mun_001 = '01' AND par_001 = '05' AND cpo_001 = '018';

Verificar el id min y máx del detalle de los registros repetidos:
SELECT min(id), max(id) FROM centro_poblado WHERE reg_001 = '06' AND est_001 = '14' AND mun_001 = '01' AND par_001 = '05' AND cpo_001 = '018';

La verdad es que luego descubrí que se podía hacer así:
SELECT * FROM centro_poblado AS a
WHERE EXISTS(
SELECT cpo_001, COUNT(cpo_001)
FROM centro_poblado
WHERE a.cpo_001= cpo_001
GROUP BY cpo_001
HAVING COUNT(cpo_001)>1)
ORDER BY cpo_001

Eliminar los registros repetidos, menos 1:
DELETE FROM centro_poblado WHERE reg_001 = '06' AND est_001 = '14' AND mun_001 = '01' AND par_001 = '05' AND cpo_001 = '018' AND id > 1;

Esto también se puede resolver con una tabla temporal, y metiendo la consulta en una función y todo eso, pero aun no lo he probado...

Finalmente, y gracias a la lista de usuarios de postgres y su histórico, me encontré [1]:
DELETE FROM centro_poblado WHERE ctid NOT IN (SELECT min(ctid) FROM centro_poblado GROUP BY cpo_002, reg_001, est_001, mun_001, par_001);

[1]http://archives.postgresql.org/pgsql-es-ayuda/2007-01/msg00353.php

jueves, septiembre 10, 2009

Jugando con los privilegios de accesos a Bases de Datos PostgreSQL

El escenario varias BDs con
  • Un usuario diferente para cada BD con privilegios para insertar/modificar
  • Un usuario capaz de leer todas las BDs
  • Un usuario admin de todas las BDs
  • Un Rol, que agrupe todos los usuarios y no tenga ningún privilegio
CREATE ROLE dba NO LOGIN;
CREATE USER user1 IN ROLE dba LOGIN ENCRYPTED PASSWORD '123456';
CREATE USER user2 LOGIN ENCRYPTED PASSWORD '123456';
CREATE USER admin1 IN ROLE dba LOGIN ENCRYPTED PASSWORD '123456';

ALTER GROUP dba ADD USER user2;

CREATE DATABASE db1 OWNER TO user1;
CREATE TABLE tabla1 (id serial, nombre character varying(10));

quitar todos los privilegios sobre la tabla: tabla1 para los usuarios user1 y user2
REVOKE ALL ON tabla1 FROM user1;
REVOKE ALL ON tabla1 FROM user2;

otorgar privilegios de consulta sobre la tabla talba1 para el usuario user1
GRANT SELECT ON tabla1 TO user1;

otorgar privilegios para insertar datos sobre la tabla tabla1 para el usuario user2 (requiere privilegios sobre la secuencia de la tabla)
GRANT INSERT ON tabla1 TO user2;
GTANT UPDATE ON tabla1_id_seq TO user2;

Para poder actualizar/eliminar un registro, se requiere tener privilegios de selección (requiere privilegios sobre la secuencias de la tabla)
GRANT UPDATE ON tabla1 TO user2;
GRANT DELETE ON tabla1 TO user2;

miércoles, septiembre 09, 2009

Migrando capas shape (.shp) a postgis

El tema de pasar capas .shp a postgis, no sé sí será una manía, pero el tema de acceso a bases de datos contra el acceso a archivos no lo creo...

Resulta que en el trabajo, hay un poco de gente haciendo capas y capas de mapas en software propietario... alguna vez pregunté (en pasillo) sí se habían puesto de acuerdo sobre algunas normas para hacer esas capas y me miraron como sí gubiera hablado en húngaro! y pensé... coño!

No me equivoqué... cuando me dieron la tarea de montar un servidor de mapas y empecé a pedir las capas, empezaron mis dolores de cabeza... ahora, me toca ver cómo hacer, y escribir (acá) para que la cosa funcione...

Vale decir que no tengo conocimientos en el tema de cartografía... por ahora...

Existen varias formas, una de ellas es con el comando shp2pgsql, otra con QGis y otra con gvSIG (esas son las que yo conozco)...

shp2pgsql: debería funcionar con algo parecido a esto
shp2pgsql -W UTF-8 .shp <schema>.<tablename> ><filename>.sql
pero yo obtuve un mensaje de error por la codificación en la que está hecha la capa, o la mala norma de los atributos

Finalmente amprendí algo sobre el estándar a seleccionar para que la cosa funcione. No significa que haya entendido, pero lo aprendí. Existe algo que se llama Sistema de Coordenadas Proyectadas y Sistema de Coordenadas Geográficas, ambas tienen como Sistema de Coordenadas de Referencia WGS84, pero la primera utiliza UTM y al segunda no, de manera que para la región Los Andes (Venezuela) sería para el primer caso SRC: EPSG 32619 que tiene WGS84 / UTM 19N y para el segundo caso SRC: EPSG 4326. De manera que es importante recordar este detalle para las propiedades de los proyectos y capas...

QGis:
  • verifico en las propiedades del proyecto que el Sistema de Referencia de Coordenadas (SRC) esté en WGS 84 (EPSG 4326 o 32619 según sea el caso)
  • Añado la capa vectorial (.shp)
  • verifico las propiedades de la capa que tenga el datum WGS 84
Importando la capa (.shp) a PostGIS:
  • Deseleccionar la opción Usar SRID por omisión o especificar aquí (que trae por defecto -1)
  • cambiar el -1 por 4326 (o el que corresponda)
  • añadir la capa
  • ok
gvSIG:
  • Agragar una vista nueva
  • Verificar en Propiedades la Proyección Actual, que por defecto viene en 23030 (España), con lo cual seleccionamos 4326 o 32619 (u otra, según sea el caso)
  • Click al botón Abrir, para añadir una capa .shp
  • Al seleccionar la opción de añadir una capa, verificamos que tenga en Proyección Actual, el mismo valor que hemos puesto a la vista. Añadios la capa
  • Seleccionada la capa a exportar, menú -> capa -> exportar -> postgis
  • llenamos los datos que nos solicitan (nombre de la tabla, datos para la conexión con la BD) y listo!
En todo esto, seguro hay algunas otras consideraciones a tomar en cuenta. Sí algiuen las sabe, paselas, sino, esperémos a descubrirlas...

Normas de cortesía para trabajar con Bases de Datos

Justo ahora que me encuentro tratando de montar un servidor de mapas, con un conjunto de capas .shp generadas por estudiantes, pasantes, tesistas y profesionales del área (no informáticos) me encuentro con algo que creo será todo un dolor de cabeza... la falta de cortesía!

Claro! ellos no tienen la culpa, como siempre, la culpa es de la vaca (para los que no saben, ese es el título de un libro, sí alguien cree que le suena interesante, pues, búsquelo, y leálo)... ¿cuál vaca? la que sea, no importa! cuando les dije que por favor, no utilizaran en los nombres de atributos (atributos en SIGs son las tablas de BD para los informáticos) carácteres acentuados, ni especiales, ni mayúsculas, me respondieron: "Cómo vamos a irrespetar la ortografía! sí es un nombre propio, claro que irá en mayúscula!"

A lo que pensé... coño!

Para los que puedan, corran la voz!!! siempre que un producto informático, tenga como futuro una base de datos, aunque sea remoto, por favor, recordar:
  • No utilizar caracteres especiales (vocales acentuadas, eñes, etc)
  • No utlizar combinaciones de mayúsculas/minúsculas
  • Utilizar nombres descriptibles
  • En caso de ser nombres muy largos, utilizar nemotécnicos y su respectivo diccionario
A medida que vaya recordando (o tropezando) agregaré a la lista... o sí algún lector se le ocurre colaborar...

martes, septiembre 08, 2009

Preparando un entorno SIG en Debian Lenny

Para la presentación de datos georeferenciados, a través de un servicio web, voy a instalar un servidor de mapas. Ahora no recuerdo los detalles porque ya lo tengo instalado, pero trataré de ir corrigiendo en caso de que haga falta.

aptitude install cgi-mapserver mapserver-bin mapserver-doc gdal-bin proj proj-bin proj-data php5-mapscript

Sí algo me falta, es probable que aptitude se los traiga. con esto ya quedaría instalado el servidor de mapas.

Cómo accederlo todavía estoy revisando la doc, pero en un navegador al teclear http://localhost/cgi-bin/mapserv te debería devolver algo como No query information to decode. QUERY_STRING is set, but empty.lo que dice que ya está funcionando. Una vez se tenga una capa para mostrar, también se puede cargar vía http://localhost/tu_path_al_template/

El qué y cómo mostrar, vienen en la próxima entrega del blog... generar el mapfile y trabajar con la plantilla, que por ahora, me tiro a OpenLayers

lunes, septiembre 07, 2009

Migrar BD de Mysql a PostGreSQL (parte 3)

Conversión de tipos

Resulta, que cuando vemos lo que nos dice el espejo que hemos creado de mysql sobre postgresql con dbi-link, los campos son creados como tipo text, con un comentario en la vista que dice qué tipo de dato aproximado debería haber ahí...

Esto es así, porque los tipos de datos entre diferentes gestores normalmente no son iguales, es decir, todos aplican los estándares, pero además, cada uno le da su toque, de manera que es posible que tenga más o menos, y que de paso, se llamen diferentes... o más bien, se le aplique aliases...

El tema es que cuando trato de leer para insertar en otra tabla, en un proceso de migración, debo tener muy presente los tipos de datos, ocasionalmente, podría recibir un mensaje del tipo:

Error de SQL:

ERROR: la columna «id» es de tipo integer pero la expresión es de tipo text
LINE 1: INSERT INTO cultu03 (id, cultu02_001, cultu03_002) (SELECT c...
^
HINT: Necesitará reescribir la expresión o aplicarle una conversión de tipo.

En la declaración:
INSERT INTO cultu03 (id, cultu02_001, cultu03_002) (SELECT codcat, codedi, catedi FROM sir_cultura_catedi)

Con lo cual, cualquiera se asusta a la primera... y no hace falta... con leer el mensaje y fijarme en la frase "aplicarle una conversión de tipos" será más que suficiente para tener algo de calma nuevamente...

¿qué es una conversión de tipos? digamos que tenemos un campo de un tipo de dato (p.e. text), pero queremos "interpretar" su contenido como sí fuera otro tipo de dato (p.e. int)... a eso se le conoce como conversión de tipos

INSERT INTO cultu03 (id, cultu02_001, cultu03_002) (SELECT codcat::int, codedi::int, catedi FROM sir_cultura_catedi)

o

INSERT INTO cultu03 (id, cultu02_001, cultu03_002) (SELECT cast(codcat as int), cast (codedi as int), catedi FROM sir_cultura_catedi)

y listo!!!

Una consultica que tiene algo más:

INSERT INTO cultu04 (reg_001, est_001, mun_001, par_001, cpo_001, cultu04_001, cultu04_002, cultu04_003, cultu04_004, cultu04_005, cultu04_006, cultu04_007, cultu02_001, cultu03_001)
(SELECT codreg, codest, codmun, codpar, codcen, anno, nombre, direccion, telefono, correo, web,
CASE WHEN area <> '' THEN
CAST(area AS numeric)
ELSE
0
END,
codedi::int, codcat::int FROM sir_cultura_edif_det)

Creo que no hace falta explicar la estructura de las tablas, sólo entender que leo en una tabla e inserto lo que estoy leyendo, con algunas particularidades sencillas....

Una más

INSERT INTO acu03 (reg_001, est_001, mun_001, par_001, cpo_001, acu03_001, acu01_001, acu03_003, acu03_004, acu03_005, acu02_001, acu03_006, acu03_007, acu03_008)
(SELECT codreg, codest, codmun, CASE WHEN codpar = 'NA' THEN '00' ELSE codpar END, CASE WHEN codcen = 'NA' THEN '000' ELSE codcen END, EXTRACT(YEAR FROM agno)::int, tipo::int, nb_acueducto, fuentes, caudal, tratamiento::int, suscriptores, poblacion, produccion FROM servicios_acueducto)

jueves, septiembre 03, 2009

Migrar BD de Mysql a PostGreSQL (parte 1 Versión 2)

Diciendo que soy usuario Debian, no digo mucho, pero les cuento que habiendo reinstalado mi equipo de la oficina, en el momento en que estoy devolviendo las cosas a la normalidad, se me ocurrió hacer un aptitude search dbi_link y vaya sorpresa, existe!

Pues, se me ocurrió instalarlo, y probar luego, cómo sería el procedimiento para que funcione... de manera que está sería la versión 2 de Migrar BD de Mysql a PostGreSQL (parte 1)

instalarlo:
  • aptitude install dbi_link
buscar donde queda:
  • find /usr/ -iname dbi_link
crear la BD en postgresql:
  • createdb migracion
crear el lenguaje plperlu a la BD recien creada:
  • createlang plperlu -d migracion
lanzar dbi_link.sql a la BD recien creada:
  • psql -d migracion -f /path/completo/dbi_link.sql
crear la estructura que me permitirá _conectar_ con la otra BD, en este caso mysql (acá usamos el mysql.sql que viene en el example del dbi_link, que no viene con el aptitude install):
  • psql -d migracion -f /path/completo/mysql.sql
y listo! ya está el esquema con la estructura y datos que necesito leer...

martes, septiembre 01, 2009

Solucionando el error de llave pública en Debian

Hoy decidí reinstalar mi computador de la oficina, tenía Debian Etch, y me estoy halando Debian Lenny desde un netinstall de etch...

¿Por qué reinstalar en vez de actualizar? vale, porque había instalado varias cosillas que no tienen uninstall (no son productos nativos para debian) y algunos quedaron mal instalados, con lo cual el sistema se fue poneindo "fastidioso" con el tiempo...

Lo que hice: instalar sólo el sistema base, esto es, que cuando llegó el tasksel, le dije que nada de eso, de manera que instaló algunos 8 paquetes más y listo. Luego, edité el sources.list para colocar uno que tengo cerca, y al darle aptitude update me saltaron 2 errores relacionados con las llaves, uno para el security y otro para el mirror que yo había agregado...

La solución:
gpg --keyserver subkeys.pgp.net --recv-keys 07DC563D1F41B907 && gpg --export --armor 07DC563D1F41B907 | apt-key add -

donde el 07DC563D1F41B907 es la llave que devuelve el error, de manera que tuve que hacerlo 2 veces, primero para el mirror y luego para el security... y update!

Apache como proxy reverse

Configurando Apache como Servidor de Páginas Web para Sistemas alojados en otro server dentro de la intranet

La situación: Un servidor A que tiene Apache2 (servidor de páginas web que aloja la página web institucional) y Bind9 (servidor de nombres de dominio: DNS), un servidor B que contiene otro Apache2 (para aplicaciones a la medida de la oficina, las cuales deben ser accedidas desde la intranet pero también desde otros lugares geográficos, de manera que son accedidos desde su propio subdominio, de la forma sistemas.misitio.tal)

Siguiendo lo que dice en [1], en ele ejemplo básico, he agregado además del default modificado, una especie de vhost, que en realidad es un proxy reverse, el el servidor A:

ServerName sistemas.misitio.tal

ProxyRequests Off

Order deny,allow
Allow from all

ProxyPass / http://192.168.15.18/
ProxyPassReverse / http://192.168.15.18/

ErrorDocument 404 /

TransferLog /var/log/apache2/sistemas.access
ErrorLog /var/log/apache2/sistemas.error


En el servidor B, sólo basta que esté el site default.

Luego, buscar los módulos para instalar y activar: proxy, proxy_connect y proxy_http

reiniciar apache y listo!

[1] http://httpd.apache.org/docs/2.2/mod/mod_proxy.html

lunes, agosto 31, 2009

Configurando Apache como Servidor de Páginas Web

Configurando Apache como Servidor de Páginas Web

La situación: en la oficina tenemos nuestro propio hosting, de manera que nuestra página web y nuestras aplicaciones (de uso interno) están también alojadas por nuestros servidores... por ahora, sólo vamos con la página web institucional.

Servidor corriendo Debian Lenny, instalado por la vía tradicional (aptitude) apache2 (como la página está en drupal, pues, todo lo demás, php5, mysql etc...)

El sites activado por defecto nos sirve para la ocasión, editado, modifico el DocumentRoot y la directiva para que ambos apunten al directorio de drupal... y listo!

Ahora no recuerdo que haya sido distinto, el asunto es que dedicamos más tiempo a configurar otras cositas que espero contar mañana...

See you!

viernes, agosto 28, 2009

Montando un sitio web con Drupal (Video)

Montando un sitio web con Drupal - sexta parte

Instalar un módulo: Flashvideo

Crear un tipo de contenido exclusivo para videos institucionales

Me he guiado por [1], pero con pequeñas variaciones, que describo desde el principio. Haré una mala traducción, ya que [1] por estar publicado en drupal.org le da carácter de oficial.

Permite subir vídeos a su sitio web e incorporarlo a cualquier contenido existente en la misma

Manual para el uso del módulo de FlashVideo para Drupal.

Pasos a seguir:
  1. Descargar del sitio de Drupal el módulo (http://drupal.org/project/flashvideo)
  2. Una vez descargado, instalelo normalmente copiando el módulo en la carpeta de módulos de su sitio
  3. Luego, en el sitio debe activar el módulo
  4. El módulo, una vez instalado, se verá en la lista de módulos en: Administrar -> Configuración del sitio, c omo se muestra en la imagen 1
  5. La configuración del entorno del módulo, quedará más o menos como se ve en la imagen 2 (muestra unas notas importantes sobre los parámetros a ser fijados en php.ini, los actuales de sus sistema y los recomendados) y la imagen 3 (muestra los tipos de nodos existentes en su sistema, donde podrá ingresar a cada uno para ver el estado y opearción de cada uno. Esto es, que puede publicar videos en cualquier módulo, basta con configurar el tipo de contenido y habilitar el módulo, tal como se muestra en la imagen 4)
  6. Si se desea incrustar el vídeo en un tipo de contenido, seleccione el tipo de contenido y sus operaciones estraán marcados para este tipo de nodo. El procedimiento será el mismo para cualquier tipo de contenido. En las imágenes se muestra como la configuración de estos campos y opciones:
  7. Una vez configurado el módulo, guardar los cambios.
  8. Puede ocurrir un error semejante al mostrado en la imágen, que se resolverá descargando los controladores de S3 en [4]
  9. Descargar y extraer la carpeta. Ésta se guarda en el directorio módulos -> FlashVideo -> drivers. Luego, volver a la página de configuración y verña como el error a desaparecido.
  10. Para este módulo se pueden utilizar varios tipos reproductores de medios swf. Dos de los más utilizados, son JW Player and the Dash Media Player los cuales puedes descargar en [2]. Ahí mismo hay unas instrucciones para su instalación, las cuales también comentaré acá según mi experiencia.
  11. En mi caso, he decidido el JW Player, así que será ese el que comentaré acá cómo me ha ido... Descargado y descomprimido, hay un archivo lamado player-viral.swf el cual he renombrado a Player.swf. Éste último y el swfobject.js los he copiado en el directorio raíz de mi instalación de drupal. En [2] sugiere que se copien en el directorio files, pero mirando los logs de apache me decía que no los encontraba en el directorio padre, así que los coloqué ahí. El resto de pasos sugeridos en [2] no me han sido útiles, así que los he obviado.
  12. Finalmente, para poder verlo, he seguido lo que dice [3].
  13. El último paso, tal como dice en [1], para poder ver el vídeo insertado en el sitio, es ejecutar el cron, esto se hace de la siguiente manera, vaya a Administrar / Informe de situación y tareas de mantenimiento de cron / ejecutar cron manualmente, lo que necesita saber que cada vez cree una página para integrar un video se necesita ejecutar el cron, una vez hecho esto se puede ver el vídeo incrustado.
[1] http://drupal.org/node/496410
[2] http://www.travistidwell.com/node/177
[3] http://www.longtailvideo.com/players/jw-flv-player/
[4] http://www.travistidwell.com/files/Storage3.tar.gz

domingo, agosto 16, 2009

Empezando a estudiar de nuevo... con django

Hora de cambiar de nivel: Django

Bueno, yo aquí, haciéndome el valiente...

Resulta que en el trabajo uso php, y por un tiempo, creo, que así seguirá siendo, pero, ahora que retomé mis estudios, pensé que aprender a programar soluciones web en python sería interesante... Ahora que lo pienso, me da susto, porque noto que tengo pocas horas "libres" al día, pero bueno, como dice un profesor amigo de la (otra) universidad, "Sí no fuera por lo uno, sería por lo otro", así que nada de tenerle miedo al cuero, después de haber matado al tigre!

Soy profesional de carrera corta (3 años) y cotinúo 2 años más y obtengo el título de Ingeniero (carrera de 5 años), todavía no se para qué, pero ahi lo llevo. De paso, con todos los cambios que conlleva el siglo XXI, se plantea la nueva universidad, con nuevos paradigmas y todo ese cuento; de manera que los 2 años tienen una colección de materias, entre ellas, una que llaman el eje central de la carrera: Proyecto Socio Tecnológico, donde nos toca montarnos en un proyecto de alcance social con aporte tecnológico, que, de paso, pueda enmarcarse dentro de los planes de desarrollo del país.

Eso suena a Desarrollo Endógeno y Sobreanía Tecnológica, así que suena bien. Siendo así, demósle! y de paso, con Software Libre!!! ja! demósle pero con ganas!!!

Pues bueno, ah instalar django, plone y a hechar pa'lante... Por ahora, plone lo he instalado en mi portatil (con Debian Lenny) de dos formas, ya que es posible tener las dos instancias juntas sin estar resvueltas: vía apt-get[0] y vía tar-gz instalador unificado [1]... y funciona! Luego, django, para empezar lo he instalado vía apt-get [2] (aunque me falta revisar [3] ya que hasta el paso 4 perfecto, pero en el paso 5 hice los cambios para postgresql, se me ocurrió ejecutar /manage.py startapp [appname] como sugiere la bienvenida de django, y zas! errores saltaron), ya veré que cosa...

Por lo pronto, así voy, espero hoy mismo publicar otra entrada, de cómo voy...

[0]http://plone.org/documentation/how-to/plone-on-debian-etch/
[1]http://plone.org/countries/conosur/documentacion/instalando-plone-3-con-el-instalador-unificado
[2]http://www.howtoforge.com/installing-django-on-debian-etch-apache2-mod_python
[3]http://codespatter.com/2008/10/15/setting-up-apache2-mod_python-mysql-and-django-on-debian-lenny-or-ubuntu-hardy-heron/

miércoles, agosto 12, 2009

Montando un sitio web con Drupal (Editor WYSIWYG)

Montando un sitio web con Drupal - quinta parte

Instalar un Módulo: Editor WYSIWYG

En la anterior instalación había mirado y probado un par, así que ahora me voy por el que tenía: FCKEditor

Este módulo parecería ser más laborioso de dejar listo para usar, pero no será tanto...

Tal y como dice el COPY_HERE.txt que viene en el módulo (fckeditor/fckeditor/) hay que descargarse de la página oficial el fckeditor.algo (tar.gz en mi caso), descomprimir, copiar todo su contendio y pegarlo dentro de la carpeta donde está el .txt ya mencionado... y listo! activar el módulo, configurarlo en el menú Configuración del Sitio y ya se puede empezar a utilizar el editor WYSIWYG.

Montando un sitio web con Drupal (Buscador, Encuesta y Formulario)

Montando un sitio web con Drupal - cuarta parte

Instalar un Módulo: Buscador

Mirando la lista de módulos del Core Opcional, he encontrado que hay un Search, una vez activado, tiene algunas cositas de configurar, tal como la indexación del sitio, mínimos de palabras coincidentes, y otros... Luego, activo el Bloque que aparece como formulario de búsquedas, y ya se muestra en el sitio.

Instalar un Módulo: Encuesta

También en la lista de módulos del Core Opcional hay un módulo Poll, que permite encuestas sencillas. En la sección de Bloques, aparece como Encuesta más reciente, fijar donde se queire ver y listo! En agregar un contenido nuevo, aparece Encuestas, es tan sencillo como escribir la pregunta, y las opciones de respuesta, opcionalmente tiene la duración, sí está cerrada la encuenta, etc...

Instalar un Módulo: Formulario de Contacto

Una vez más, aparece un módulo en el Core Opcional Contact que habilita el uso de formularios de contacto personal y a nivel sitio. Activado! Luego lo configuro y comento...

martes, agosto 11, 2009

Montando un sitio web con Drupal (Calendario)

Montando un sitio web con Drupal - tercera parte

Instalar un Módulo: Calendario

Necesarios: Views, Date, Content (CKK)

Lo primero que se debe hacer para instalar un módulo, es navegar por el enorme listado de módulos que existen, de manera que hay que armarse de paciencia y dedicar un buen rato a eso.

El Módulo calendar dice que depende de los módulos views, date, adicionalmente el módulo date depende de content que está en CKK, de manera que los he descargado e instalado. De manera que activo:
  • CKK:
    • Content
  • Date (Fecha / Hora)
    • Calendar
    • Date
    • Date API
    • Date Timezone
  • Views
    • Views
    • Views UI

Luego, en el menú Construcción del Sitio -> Views, activo la vista del calendar, finalmente agrego el bloque Calendar. al darle guardar ya sale el Calendario... salvo por el siguiente mensaje, que tiene que ver con la configuración de fecha del manejador de la Base de Datos (ya tendré que chequearlo, pues desaparece al continuar con el trabajo):
  • warning: pg_query() [function.pg-query]: Query failed: ERROR: error de sintaxis en o cerca de «'2008-02-15 12:00:00 UTC'» at character 1 in /var/www/drupal/includes/database.pgsql.inc on line 139.
  • user warning: query: '2008-02-15 12:00:00 UTC' AT TIME ZONE 'US/Central' in /var/www/drupal/modules/date/date_api_sql.inc on line 96.

Montando un sitio web con Drupal (Noticias)

Montando un sitio web con Drupal - segunda parte

Instalar un Módulo: Noticias

Mirando la lista de módulos, he encontrado varios
  • Innovation News
  • Google News (permite "inscrustar" noticias de Google en el sitio)
  • News Page
Éste último, require el módulo Aggregator que está en el Core Opcional. Este módulo aggregator es para Integra contenido sindicado RSS, RDF y Atom. Adicionalmente, es el más sencillo de utilizar... por ahora, con ese me quedo... al rato probaré el Innovation News y les cuento

Montando un sitio web con Drupal (primera parte)

Montando un sitio web con Drupal - Primera parte

Empezando: instalación inicial

En mi trabajo tenemos nuestro propio hosting, así que muchos de los traspies nos llevamos nosotros mismos... En realidad ya tenía un sitio montado y funcionando con Drupal, pero ocurrió el desastre! se dañó el disco duro del servidor y no tenías más que unos respaldos de hace más de 6 meses... y yo, que fue quien montó el drupal, no tenía nada documentado, otro desastre!

Pues bien, he decidido apuntar todo acá, esta vez voy a ir montando módulo por módulo, y a cada uno lo voy a escribir por acá, a efectos de que no se me olvidé y no tenga el desorden que tenía (al menso intentaré minimizarlo). De paso, al tiempo que sirva como recordatorio (como siempre, chuletario), pueda que alguien que necesite consiga informaicón, y por último, quizás alguien sepa cómo hacer mejor algo de lo que yo escribo y me tire una mano...

Lo primero, una instalación tan normalita como la tira la página oficial, sobre postgresql, incluso con mi idioma por defecto. En la primera entrada, dice en inglés, que para cambiar el idioma simplemente hay que descargar el paquete, descomprimir y copiar todo en la raiz de drupal. tuve mis dudas, pero como es local en mi computadora ¿qué podía perder? tan cierto como decía la instrucción.

lunes, julio 20, 2009

Auditoria para los registros de BD en Postgresql con tablelog (I parte)

Es posible, que alguna vez haga falta realizar auditoría de los datos de algún sistema. Algo así como, quien hizo qué y cuándo. Dicho de otro modo, supongamos que existe el sistema de catastro de X institución, y que varios usuarios alimentan, de manera que varios usuarios podrían, ocasionalmente, insertar, modificar y/o eliminar registros... ¿pero cuál de ellos insertó/modificó/eliminó el registro X? de algo de eso se trata esto...

Existen varias formas de realizar este tipo de auditorías, siempre va a depender de la necesidad, por lo que el más seguro será el que esté hecho a la medida. También, existen diferentes formas de hacerlo, revisando los logs del sistema, etc.

En este post, sólo trataré de traducir lo que dice en el sitio oficial de tablelog y mis comentarios sobre el cómo lo estoy haciendo funcionar.

Paso a paso:
  1. Descargar los fuentes de: pgfoundry http://pgfoundry.org/projects/tablelog
  2. Desempaquetar el archivo, cambiarse la directorio donde acaba de descomprimirse, y ejecutar en la cónsola: make -f Makefile.nocontrib . Esto debería ejecutar sin problemas, sí obtiene algún error, es posible que necesite la versión de desarrollo de su versión de Postgresql. Sí la compilación se realizó con éxito, la librería ya está instalada.
  3. Como root, ejecutar: Makefile.nocontrib make-f install . Esto instalará la biblioteca en el directorio de la biblioteca de PostgreSQL.
  4. Ahora le decimos a la BD que queremos utilizar tablelog. Recordemos que tenemos que tener plpgsql instalado para la BD a auditar. Conectados como superusuario (de la BD) ejecutamos para la BD que deseamos el script: table_log.sql . Además de crear la estructura necesaria, le creará un par de tablas (test y test_log) para que pueda observar más o menos el funcionamiento de tablelog.
  5. Después de esto usted puede añadir algunas funciones de apoyo que harán la vida más fácil, usted puede encontrar en el archivo table_log_init.sql.
Y esto es todo, ahora puede utilizar tablelog en su base de datos. Con tablelog se pueden hacer algunas otras cosas algunas, de las que se habla en el sitio original... y en el código fuente jeje

martes, junio 23, 2009

VI Foro de Conocimiento Libre: Construyendo en Comunidad


El VI Foro Mundial de Conocimiento Libre se realizará en la ciudad de Mérida, Estado Mérida desde el 4 al 8 de Mayo de 2009. El Centro Cultural Tulio Febres es el recinto que acogerá este evento.

El VI Foro Mundial de Conocimiento Libre es un evento internacional, multitemático, abierto e incluyente organizado en conjunto con comunidades de investigadores, profesionales y usuarios, la empresa privada y el Gobierno Bolivariano.
Ejes Temáticos

Este año, el Foro Mundial de Conocimiento Libre abarcará temas englobados en varias áreas de interés. Es importante resaltar que en esta edición se busca dar énfasis a la construcción de comunidades locales para la construcción de conocimiento libre.

Las actividades estarán entre charlas, talleres, juegos, demostraciones, plenarias y demás.

Visita: http://viforo.solve.net.ve/

jueves, junio 18, 2009

Campos calculados desde PostGreSQL (I)

Vale... He aquí la necesidad: Necesito una consulta que entre sus resultados, hay una columna que es calculada de la forma:

r = ((a / b) * 1000)

donde b debe ser mayor que cero, obviamente

En SQL (para postgresql) va algo así:

SELECT
CASE WHEN SUM(b) > 0 THEN
round(((SUM(a) / SUM(b)) * 1000),2)
ELSE 0
END
AS rendimiento
FROM miTabla

miércoles, junio 17, 2009

Viveza Criolla

Viveza Criolla es el título de una presentación que me llegó a mi correo, de esos que llegan sin uno pedirlos, ya saben, cadenas creo que le dicen...

Cosa que normalmente descarto rápidamente... Este, lo tiraría rápidamente, pues toca el tema político, tan álgido como la guerra santa entre Linux y M$, o entre Postgresql y Mysql, pero que he decidido colocarlo acá, un poco para no olvidar que tirar la basura donde no es, es una mala idea...

Lamentablemente desconozco el autor intelectual de la obra, a quien tendría que agradecer por ser tan sincero por la descripción que da a mi país y su gente (entre los que entro yo). Bue... ahí se los dejo.

“Se necesita materia prima para construir un país”

Acabo de recibir este mensaje y es uno de los mejores que he visto en mucho tiempo...

Así como empleamos el tiempo en mandar chistes a todos nuestros amigos, considero mucho más importante correr la voz con este tipo de contenidos.

Tomen de él lo que les sirva para pensar

La creencia general es que Lusinchi no servía, como así tampoco Pérez y Caldera. Hoy se dice que Chávez no sirve, pero, quienquiera que venga después de Chávez, tampoco servirá para nada.

Por eso estoy empezando a sospechar que el problema no está en lo ladrón y corrupto que haya sido Carlos Andrés Pérez, o en lo autocrático que es Chávez.

El problema está en nosotros, nosotros como pueblo, nosotros como materia prima de un País.

Porque pertenecemos a un país donde la “viveza criolla" es moneda valorada tanto o más que el dólar.

Un país donde hacerse rico de la noche a la mañana es una virtud más apreciada que formar una familia a largo plazo, basada en valores morales y respeto por los demás.

Pertenecemos a un país donde, lamentablemente, los periódicos jamás podrán venderse como se venden en otros países, es decir, poniendo unas cajitas en las aceras donde uno paga por un solo periódico y saca un solo periódico dejando los demás donde están.

Pertenecemos un país donde los lugares de trabajo son, entre otras cosas, las papelerías particulares de sus empleados deshonestos que llevan a su casa, como propias, hojas de papel, lapiceros, bolígrafos, lápices, marcadores y todo lo que pueda hacer falta para la tarea de sus hijos.

Pertenecemos a un país donde la gente se siente triunfante si consigue colgarse del cable del vecino y donde la gente “inventa’’ a la hora de llenar sus declaraciones, para pagar menos impuestos, o directamente para no pagarlos.

Pertenecemos a un país donde la impuntualidad es un hábito, donde los directivos de las empresas no generan capital humano, donde las personas tiran basura en las calles y luego reclaman al gobierno porque las calles están sucias o se tapan las alcantarillas, donde no existe la cultura por la lectura y donde no hay conciencia ni memoria política, histórica o económica.

Donde nuestros diputados trabajan dos días al año (y cobran todos los demás como altos ejecutivos) para aprobar una reforma fiscal al vapor, que lo único que hace es hundir al que no tiene, joder al que tiene poco y beneficiar sólo a unos pocos.

Pertenecemos a un país donde las licencias de conducir y los certificados médicos se pueden "comprar", sin hacer ningún examen.

Un país donde puede subir una persona de edad avanzada, una mujer con un niño en brazos, o algún minusválido y la persona que viene sentada en el asiento especial para estas personas se hace la dormida para no dárselo y si alguien le reclama se levantará pero para dar un golpe o decir una mala palabra.

Un país en el cual la prioridad de paso es para los chóferes y no para el peatón. Un país donde su gente está llena de faltas, a las que ignora, pero que disfruta criticando a sus gobernantes.

Mientras más le diga rata a Pérez, mejor soy yo como persona, pese a que apenas ayer me consiguieron todas las preguntas del examen de matemáticas de mañana.

Mientras más le diga autócrata a Chávez, mejor soy yo como Venezolano, a pesar de que apenas esta mañana estafé a mi cliente a través de un fraude, lo que me ayudó a pagar algunas deudas.

No, No, No. YA BASTA!!!.

Como “Materia Prima” para un país serio, tenemos muchas cosas buenas, pero nos falta muchísimo para ser los hombres y mujeres que nuestro País realmente necesita.

Esos defectos, esa alardeada “viveza criolla" congénita, esa deshonestidad en pequeña escala que después crece y evoluciona hasta convertirse en casos de escándalo, esa falta de calidad humana, más que Lusinchi, Pérez, Caldera o Chávez, es lo que nos tiene real y francamente mal, porque éstos no han sido ni más ni menos que nuestros presidentes, óigase y entiéndase bien, nuestros presidentes, nacidos aquí y no en otra parte.

Lo siento. Porque, aunque Chávez renunciara hoy mismo, el próximo presidente que lo suceda tendrá que seguir trabajando con la misma materia prima defectuosa que, como pueblo, somos nosotros mismos. Y no podrá hacer nada.

No tengo ninguna garantía de que alguien lo pueda hacer mejor, pero mientras nadie señale un camino destinado a erradicar primero los vicios que tenemos como pueblo, nadie servirá.

No sirvió Lusinchi, ni Pérez, ni Caldera, no sirve Chávez, ni servirá el que venga. ¿O qué?... Es que necesitamos traer a un dictador, para que nos haga cumplir la ley por la fuerza y a los palos?

Aquí hace falta otra cosa, algo más que “cacerolazos” o “marchas”. Y mientras esa "otra cosa" no empiece a surgir desde abajo hacia arriba, o desde arriba hacia abajo, o del centro para los lados, o como quieran, seguiremos igualmente condenados, igualmente estancados... igualmente sumergidos!!!

Es muy bueno ser Venezolano. Pero cuando esa Venezolaneidad autóctona empieza a hacerle daño a nuestras posibilidades de desarrollo como Nación, ahí la cosa cambia...

No esperemos encenderle una velita a todos los Santos, a ver si nos manda un Mesías. Si nosotros tenemos que cambiar, un presidente diferente, con los mismos Venezolanos, no se podrá hacer nada.

Está muy claro... Somos nosotros los que tenemos que cambiar.

Ahora, después de este mensaje, francamente he decidido buscar al responsable, no para castigarlo, sino para exigirle (sí, exigirle) que mejore su comportamiento y que no se haga el que no oye, el que no entiende.

Sí, he decidido buscar al responsable! Estoy seguro que lo encontraré apenas me mire en el espejo Ahí estará, no necesito buscarlo en otro lado. y tu, ¿que piensas?......
REFLEXIONA CARAJO!!!!!

martes, junio 02, 2009

VIT Serie D2000, configurar video y compiz

Un poco, para que no se me pierda de vista, un blog en el que hablan sobre la configuración del video a 1280 x 800 y la instalación de compiz en la VIT

http://laptop-vit.blogspot.com/

Vale decir que para mi portátil, el xorg.conf queda algo distinto, al rato lo copio por acá...

jueves, mayo 28, 2009

Migrar Datos de una tabla a otra, con ligeras diferencias

Eu!

Siguiendo el tema de las migraciones, recientemente me tocó que pasar unos datos, de una tabla a otra, que contenían ligeras diferencias, par de campos de tipo real y double precsion pasaban a ahora a numeric, más algunos campos menos que tenía la tabla destino.

Sencillo, me hice una query que insertara según lo que leyera:

INSERT INTO agri04 (id, reg_001, est_001, mun_001, par_001, cpo_001, agri04_001, agri03_001, agri04_003, agri04_004, agri04_005, agri04_006, agri04_007, agri04_008) (SELECT id, codreg, codest, codmun, codpar, codcen, EXTRACT(YEAR FROM fecha), id_det, fund, reno, ssem, scos, prod, valor FROM agricolav);


El tema de los tipos de datos, en vista de la fortuna de que ambos eran números con decimales, sólo tuve que seleccionar el tamaño de los numerics, que al final quedaron de (12,2) algunos, y otros de (10,2).

Otro caso:

INSERT INTO municipios
(gid, id, municipio, estado, the_geom)
(SELECT gid, id, municipio,
CASE
WHEN estado = 'Mrida' THEN 14
WHEN estado = 'Tchira' THEN 20
WHEN estado = 'Trujillo' THEN 21
END,
the_geom FROM municipios_region);

viernes, abril 17, 2009

Conectar Postgis a Postgresql

Hola... como siempre, esto es para yo tener dónde buscar cuando se me olviden las cosas... sí de paso le sirve a alguien, pues... quizás publique mi número de cuenta por sí quieren donar algo, jajajaja, es broma...

Para que una BD (en Postgresql), pueda servir a efectos de un SIG, debemos trabajar con Postgis, de manera que, creamos la BD:
CREATE DATABASE mapas;
CREATE LANGUAGE plpgsql;

Obviamente debemos tener instalado postgis, que en Debian es suficiente con aptitude install postgresql-tuversion-postgis (por si dudas, aptitude search postgis), con lo que en /usr/share/postgresql-miversion-postgis/ tengo los .sql necesarios.

psql -d mapas -f lwpostgis.sql
psql -d mapas -U carbonara -f spatial_ref_sys.sql

y listo! ya la BD mapas se puede utilizar como almacen de un SIG

jueves, abril 02, 2009

Migrar BD de Mysql a PostGreSQL (parte 2)

Después de no sé cuánto tiempo me he decidido a migrar la BD que tengo en mysql a Postgresql. Las razones no son importantes, o más bien es justamente eso, son datos tan importantes que es un crímen tenerlos en mysql...

Para esta demostración voy a utilizar unas tablas básicas que son similares a esto:

CREATE TABLE `Region` (
`codreg` char(2) NOT NULL default '',
`nomreg` varchar(35) NOT NULL default '',
PRIMARY KEY (`codreg`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Tabla de Region';

CREATE TABLE `Estado` (
`codreg` char(2) NOT NULL default '',
`codest` char(2) NOT NULL default '',
`nomest` varchar(35) NOT NULL default '',
PRIMARY KEY (`codreg`,`codest`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Con estas dos tablas se pueden observar ya varios detalles, la utilización de mayúsculas y minúsculas para el nombre de las tablas y la falta de integridad referencial, por otro lado la nueva BD está en utf8 (no es de mi agrado, pero es el acuerdo en que se llegó en la oficina).

Una vez hecho lo escrito en la primera parte de este post he creado un esquema dentro de la misma BD en Postgresql, de manera de leer y copiar en la misma BD, pero en diferentres esquemas. El esquema lo he llamado migracion, donde debo crear las tablas tal y como las necesito, de manera que:

CREATE TABLE region (
codreg character varying(2) NOT NULL,
nomreg character varying(50) NOT NULL
);

ALTER TABLE migracion.region OWNER TO carbonara;

ALTER TABLE ONLY region
ADD CONSTRAINT region_pkey PRIMARY KEY (codreg);

CREATE TABLE estado (
codreg character varying(2) NOT NULL,
codest character varying(2) NOT NULL,
nomest character varying(50) NOT NULL
);

ALTER TABLE ONLY estado
ADD CONSTRAINT estado_pkey PRIMARY KEY (codreg, codest);


ALTER TABLE ONLY estado
ADD CONSTRAINT estado_fkey FOREIGN KEY (codreg) REFERENCES region(codreg) ON UPDATE CASCADE ON DELETE RESTRICT;

Luego, el sql que lee de un lado y escribe del otro:
INSERT INTO migracion.region (codreg, nomreg) SELECT codreg, nomreg FROM "Region";
INSERT INTO migracion.estado (codreg, codest, nomest) SELECT codreg, codest, nomest FROM "Estado"

y listo! Todavía no entiendo por qué me tardé tanto en escribir este post, pero bue...

martes, enero 06, 2009

P4A: el main de mis aplicaciones

Hace un par de meses que he tratado de mirar los frameworks de desarrollo para ganar tiempo, ya que en el trabajo, el tiempo no es lo que más sobra... finalmente, me decidí a probar uno, P4A un RAD de PHP.

La propaganda de lo bueno, se los dejo para que lo revisen en la propia página del proyecto.

Como siempre, lo que necesito es tener donde buscar cuando no me cuerde de algo... de paso, como no soy programador avanzado, quizás a alguién más como yo, le pueda servir...

Estoy tratando de que los sistemas hechos en el trabajo (y los míos propios) tengan una especie de información sobre la autoría del proyecto (donde, con qué, por qué con eso, etc... además del quién, claro está), de manera que una de las opciones del menú está siendo la página principal donde espero encontrar cómo explicar esos detallitos...

Para empezar, no por el principio (index), tengo un main.php así:
setTitle("lugar donde trabajo

oficina a la que pertenezco

nombre del sistema

Bienvenidos");

$icono =& $this->build("p4a_image","icono");
$icono->setIcon("gnome-globe.png");

$this->build('P4A_Message',"mensaje")
->setIcon('status')
->setValue("contenido descriptivo");

$frm =& $this->build("p4a_frame","frame");
$frm->anchorCenter($icono);
$frm->anchorCenter($this->mensaje);

$p4a =& p4a::singleton();

$this->display("menu", $p4a->menu);
$this->display("main",$frm);
}
}
?>
Se entiende? espero que sí, sino, pregunta...

Entre lo poco que puedo decir:
setTitle: que permite definir un título a la máscara. Talcual escribamos ahí, aparecerá
El objeto P4A_Image: que permite definir una imágen para publicar en la máscara
El objeto P4A_Message: que utilizo para tirar un texto cualquiera, que describa el sistema. Podría utilizarse para meter algunos tips de ayuda del sistema, por ejemplo.

Subversion 1ra parte: Repositorio Local

Buscando un poco se encuentran muchos enlaces sobre qué es subversion, cómo instalarlo, configurarlo y usarlo, pero como cada quien tiene su manera de explicar, es posible que me resulte más fácil entender mis garabatos...

Para esta parte, me ha ido bien:
http://picandocodigo.net/2008/08/repositorio-subversion-local/
http://sherekan.com.ar/2008/03/25/instalacion-configuracion-y-uso-de-subversion-en-linux/

Instalación
En mi caso, uso Debian Linux, así que:

aptitude install subversion

Configuración
Crear un grupo, donde se incluirán todos los usuarios que podrán acceder al servidor de control de versiones:

groupadd subversion


Agregar el primer usuario, o sea, a mi, al grupo que acabamos de crear:

addgroup cesar subversion

Tengo un directorio de desarrollo bajo /var/www con el nombre de sistemas, y uno para pruebas en mi home, llamado desarrollo, de manera que tengo /var/www/sistemas y /home/cesar/www/desarrollo, ahora bien, voy a crear el directorio donde estarán los repositorios de versiones en mi home, quedando: /home/cesar/www/svn donde creare mi primer repositorio

computacion06:/home/cesar/www/svn# svnadmin create viaticos

Como estoy en un máquina local, la importación de archivos al repositorio de versiones, sería algo así:

svn import /var/www/sistemas/viaticos file:///home/cesar/www/svn/viaticos/


y listo! aún no se qué está listo, pero está! jeje