Archive for January, 2008
January 24, 2008 a las 5:29 pm por Edwin Plauchu · Archivado en Varios
Se utiliza la version de mysql 5.0.19 en este howto…
Espero y lea sea util a mucha gente……..
Mysql-Cluster <— ojo es un archivo en formato postscript y para descargarlo, den click al boton derecho de su navegador,… en save liks as….
January 23, 2008 a las 12:36 pm por Edwin Plauchu · Archivado en Linux
Después de leer la queja de un usuarios aun windowizado, y las respuestas un tanto agresivas. Creo que es necesario reconocer que debmos aceptarlo, es una pesadilla lidiar con “dependeincas y librerias”. Mejor informo de una técnica para solucionar este problema.
En linux se puede hacer todo, pero luego las herramientas “automágicas”, nos “nublan la visión y el fuente no es lo suficientemente explícito”. Así que si alguna vez han tenido broncas de librerías no resueltas, quizás ésto les pueda ayudar…
El uso de las librerías, te permite que, si tu programa necesita o quieres que maneje llaves de encriptación, simplemente “usas las funciones que te da el openssh”. Así no tienes que “programar” el openssh tú solito. Nada más lo usas y eso te da, reduccion de tiempo de desarrollo, una mayor calidad del software y menores costos. El problema radica en que el sistema “objetivo”, es decir nuestra maquina, no satisfaga esas dependencias, y entoces el baile y dolor de cabeza comienza. Así que aquí van un par de aspirinas para eso.
Debian, Red Hat, y sus derivados, no hacen la detección de las librerías, “automágicamente”. Linux provee un mecanismo con el cual uno puede saber que librerías requiere un programa, y si las tenemos o no.
Para hacer las cosas “optimas”, linux maneja un caché de librerías.
Este caché de librerías, es controlado por la aplicación “ldconfig”, y su archivo de configuración es ld.so.conf, el cual se encuentra en /etc.
Por lo tanto, tenemos:
Archivo de configuración de las librerías: /etc/ld.so.conf
Archivo que manipula el caché de las liberías: ldconfig
Con ésto, ya tenemos una primera idea de quien maneja la “disponibilidad” de las librerías. Ahora el problema es saber qué librerías usa un programa.
Simple, para eso está el comando ldd, el cual nos dice qué programa usa cual libreriá.
Ejemplo (andi pue’, ¡hasta con ejemplo!).
bash-2.05a$ which nslookup
/usr/bin/nslookup
bash-2.05a$ ldd /usr/bin/nslookup
libdns.so.5 => /usr/lib/libdns.so.5 (0×40021000)
libcrypto.so.0 => not found
libisc.so.4 => /usr/lib/libisc.so.4 (0×4010b000)
libnsl.so.1 => /lib/libnsl.so.1 (0×4013a000)
libc.so.6 => /lib/libc.so.6 (0×4014f000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0×40000000)
Primero uso el which para encontrar donde en mi sistema está la utilería “nslookup”.
Después uso ldd para saber las librerías que usa el programa de la cual sale mucha información.
La información esta estructurada en dos columnas.
La primera columna es la “librería” solicitada y la segunda columna es la ruta de la librería y el punto de entrada a la misma.
Si se fijan, tengo un problema de librerías. Me dice que:
libcrypto.so.0 => not found
No la encontró, así que tengo “dependencias no resueltas”.
¿Qué sigue? Buscar esa libreria en mi sistema.
find / -name “libcrypto.so.0″
lo cual me dice:
/usr/local/mylibs/libcrupto.so.0
Entonces sí tengo mi libreria, pero no me la “encuentra el sistema”, ¿entonces? ¿qué sucede? Simple, hay que “actualizar” mi sistema de caché:
Reviso mi /etc/ld.so.conf que contiene las rutas de búsqueda de las librerías, en mi caso particular:
bash-2.05a$ more /etc/ld.so.conf
/usr/local/lib
/usr/X11R6/lib
/usr/i386-slackware-linux/lib
/opt/kde/lib
/usr/lib/qt/lib
/usr/lib/qt/lib
Por lo tanto, edito mi /etc/ld.so.conf y agrego la ruta donde la librería se encuentra y mi /etc/ld.so.conf ahora dice:
bash-2.05a$ more /etc/ld.so.conf
/usr/local/lib
/usr/X11R6/lib
/usr/i386-slackware-linux/lib
/opt/kde/lib
/usr/lib/qt/lib
/usr/lib/qt/lib
/usr/local/mylibs
Ahora, actualizo mi “caché de librería” al ejecutar ldconfig
y vuelvo a probar el ldd sobre nslookup:
/usr/bin/nslookup
bash-2.05a$ ldd /usr/bin/nslookup
libdns.so.5 => /usr/lib/libdns.so.5 (0×40021000)
libcrypto.so.0 => /usr/local/mylibs/libcrypto.so.0 (0×400a1000)
libisc.so.4 => /usr/lib/libisc.so.4 (0×4010b000)
libnsl.so.1 => /lib/libnsl.so.1 (0×4013a000)
libc.so.6 => /lib/libc.so.6 (0×4014f000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0×40000000)
Listo. Dependendicas completadas.
Ahora, si el paso del “find” falla, pues eso significa que definitivamente no tengo esa libreria y hay que conseguirla. Google o Freshmeat, nos ayudan a esto.
El rpm y el apt-get, hacen prácticamente ésto. Así que si tú tienes un problema con un .tar.gz o algo así que te bajas “precompilado”, ya lo puedes resolver tú, que a diferencia de Windows, no puedes, a menos que utilices caras herramientas de desarrollo.
Ahora, cabe hacer mención, que no hay un procedimiento “perfecto”. Digamos que éste procedimiento es básico. Cuando éste falla se puede emplear strace o el gdb para “ver” que pasa.
Como recomendaciín, te suguero que uses Slackware o Gentoo, y manejes todo “a compilar”, dado que, para que compile algo, tienes que tener satisfechas todas las dependencias; asi garantizas que todo esté en donde debe de estar.
Espero que esta información le sirva a más de uno y sepan que hacer ante un:
bash-2.05a$ nslookup
nslookup: error while loading shared libraries: libcrypto.so.0: cannot open shared object file: No such file or directory
January 23, 2008 a las 12:15 pm por Edwin Plauchu · Archivado en Programacion
Esta es una pregunta que suelen realizarme muchas veces, así que queda por escrito para futuras consultas.
Como es lógico, la fecha de ayer y mañana se calculan restando uno o sumando uno a la fecha de hoy. Pero claro, hay que indicar que lo que se suman son días, no un número entero. Esto se realiza con el módulo datetime:
#!/usr/bin/python
# -*- coding: iso-8859-15 -*-
import datetime
# La fecha de hoy es:
hoy = datetime.datetime.today()
# Para calcular la de ayer, restamos un día
ayer = hoy + datetime.timedelta(days=-1)
# Y para mañana, sumamos un día
mañana = hoy + datetime.timedelta(days=1)
January 15, 2008 a las 4:18 pm por Edwin Plauchu · Archivado en Ubuntu, Programacion, Linux
Introduccion
Lenguajes script como Perl, Python, Php, Ruby y Tcl estan recibiendo bastante atencion hoy en dia - principalmente porque estos lenguajes facilitan el desarrollo de aplicaciones y prototipos de las mismas de un modo impresionantemente acelerado. Puedo decir como experiencia que al momento de usar python, el tiempo de desarrollo ha sido drasticamente bajo - con la ventaja agregada de la robustes y flexibilidad del codigo. Pero habra situaciones en las que el scripting puro no trabajara como lo deseamos, un ejemplo tipico de esto son las aplicaciones cientificas que requieren una alta velocidad de calculo para rutinas graficas o aplicaciones que requieren controlar o coordinar hardware en base a tiempo real. Entonces he llegado a la conclucion paradigmatica de que lo que necesito es un lenguaje mezclado, en el cual lenguajes tradicionales como C/C++ realicen lo duro del bajo nivel , mientras la logica de la app la pueda realizar en modo Scripting.
Este articulo se enfoca principalmente en el uso de una herramienta que se enfoca a la creacion de Wrappers, con la intencion de integrar el codigo escrito en C/C++ con el popular lenguaje scripting Python. Los fragmentos de codigo en este articulo fueron probados sobre un ubuntu gutsy y una version de Python 2.5.1. Espero que todo eso te sean tan util como a mi.
Obtener SWIG
SWIG es desarrollado por Dave Beazley y puede ser descargado de www.swig.org. o bien puedes instalaro mediante la herramienta apt-get de tu debian… ojo tambien requieres g++ y python2.5-dev.
apt-get install swig g++
Un ejemplo simple
Diremos que tenemos una funcion llamada suma(a,b) escrita en codigo C la cual nos retornara la suma de dos numeros que le sean pasados como argumentos. Veremos como usar la funcion “suma” desde Python. Crearemos el archivo de nombre aritmetica.c el cual contendra el siguiente codigo:
int suma(int a, int b)
{
return a+b;
}
Ahora ejecutaremos el siguiente comando:
swig -python -module aritmetica aritmetica.c
Esto nos retornara lo siguiente:
root@pianodaemon-laptop:/home/pianodaemon$ ls -l
total 100
-rw-r--r-- 1 pianodaemon pianodaemon 41 2008-01-15 15:48 aritmetica.c
-rw-r--r-- 1 pianodaemon pianodaemon 1605 2008-01-15 15:48 aritmetica.py
-rw-r--r-- 1 pianodaemon pianodaemon 92723 2008-01-15 15:48 aritmetica_wrap.c
Observemos que fueron creado 2 nuevos archivos, aritmetica_wrap.c y aritmetica.py. Nosotros deberiamos ahora de compilar ambos aritmetica.c y aritmetica_wrap.c para producir archivos de codigo objeto, la compilacion sera con el siguiente comando:
root@pianodaemon-laptop:/home/pianodaemon$ gcc -I/usr/include/python2.5/ -c aritmetica.c aritmetica_wrap.c
Observe que ya logramos compilar el codigo objeto con exito.
pianodaemon@pianodaemon-laptop:~/gulsinborrame$ ls -l
total 136
-rw-r--r-- 1 pianodaemon pianodaemon 41 2008-01-15 15:48 aritmetica.c
-rw-r--r-- 1 pianodaemon pianodaemon 707 2008-01-15 16:15 aritmetica.o
-rw-r--r-- 1 pianodaemon pianodaemon 1605 2008-01-15 16:11 aritmetica.py
-rw-r--r-- 1 pianodaemon pianodaemon 92723 2008-01-15 16:11 aritmetica_wrap.c
-rw-r--r-- 1 pianodaemon pianodaemon 28884 2008-01-15 16:15 aritmetica_wrap.o
Ahora procedemos a generar un libreria compartida, para eso utilizaremos el enlazador de linux ld:
ld -shared -o aritmetica.so aritmetica.o aritmetica_wrap.o
Finalmente probaremos la libreria que hemos generado:
import aritmetica
>>>aritmetica.suma(10, 20)
30
>>>aritmetica.suma(10, -10)
0
>>>
January 11, 2008 a las 3:02 pm por Edwin Plauchu · Archivado en Programacion
Desde la salida de la versión 5 de MySql se pueden usar triggers en nuestras bases de datos.
Peró, ¿qué son los triggers?, son objetos relacionados con tablas y almacenados en la base de datos que se ejecutan o se muestran cuando sucede algún evento sobre sus tablas asociadas.
Los eventos pueden ser las sentencias INSERT, DELETE, UPDATE que modifican los datos de una tabla. Los triggeres se pueden ejecutar antes (BEFORE) y/o después (AFTER) de que sean modificados los datos.
Los triggers tienen dos palabras clave, OLD y NEW que se refieren a los valores que tienen las columnas antes y después de la modificación. Los INSERT permiten NEW, los DELETE sólo OLD y los UPDATE ambas.
Un ejemplo de trigger seria uno asociado a la sentencia DELETE en una tabla de clientes, para impedir que se elimine uno que tenga un saldo distinto de cero. Otro trigger seria guardar los datos que se modifican de un cliente en otra base de datos que serviria de auditoria.
Crearemos la tabla de clientes y le ponemos algunos registros:
CREATE TABLE clientes(
id int not null auto_increment,
nombre varchar(100),
seccion varchar(10),
PRIMARY KEY(id),
KEY(nombre)
) ENGINE = InnoDB;
INSERT INTO clientes (nombre, seccion) VALUES
('Miguel','informatica'),
('Rosa','comida'),
('Maria','ropa'),
('Albert','informatica'),
('Jordi','comida');
Y una tabla que será la que guardará los datos de la “auditoria”
CREATE TABLE auditoria_clientes
(
id int not null auto_increment,
nombre varchar(100),
anterior_seccion varchar(10),
usuario varchar(40),
modificado datetime,
primary key(id)
) ENGINE = InnoDB;
y finalmente un trigger que se disparará cada vez que alguien modifique un dato de la tabla clientes y lo guardará en una tabla junto al nombre del usuario y la fecha.
CREATE TRIGGER trigger_auditoria_clientes AFTER UPDATE ON clientes
FOR EACH ROW
INSERT INTO auditoria_clientes(name, anterior_seccion, usuario, modificado )
VALUES (OLD.nombre, OLD.seccion, CURRENT_USER(), NOW() );
January 11, 2008 a las 12:04 pm por Edwin Plauchu · Archivado en Windows, Programacion, GPL, FreeBSD, Linux, Solaris
Vamos a crear un buscador que busque en una tabla de nuestra base de datos y que según el número de palabras buscadas utilice LIKE o el Full Text Search de MySQL.
Que és Full Text Search?
El Full Text Search utiliza los índices de la tabla para hacer las búsquedas y hace las comparaciones de la misma forma que se hacen en los grandes buscadores y no como una comparación sencilla y costosa en tiempo como la utilizada por el like.
El resultado que devuelve es ordenado por similitud a las palabras o cadena buscada, esto se puede hacer ya que cuando va encontrando los resultados el mismo le asigna un indice de similitud a lo buscado, con lo que podemos saber lo exacto que es el resultado.
Para crear el índice en la tabla a buscar haremos:
ALTER TABLE noticias ADD FULLTEXT(titulo, texto);
Suponiendo que la tabla se llama noticias y los campos que queremos buscar són titulo y texto. Debemos tener en cuenta que los campos del índice solo pueden ser Char, Varchar o TEXT.
Nota: Los índices hacen que las tablas ocupen más espacio en disco peró agilizan mucho las búsquedas.
MATCH … AGAINST
Para buscar en la tabla utilizando el índice, haremos:
SELECT * FROM el índice WHERE MATCH(titulo, texto)
AGAINST ('palabras_a_buscar')
Si queremos saber noticias de similitud del resultado podemos hacer:
SELECT * FROM noticias WHERE MATCH(titulo, texto)
AGAINST ('palabras_a_buscar') AS similitud
Donde similitud sera el valor de aproximación a la busqueda.
Problemas del MATCH … AGAINST
El problema principal es que ens busquedas de una sola palabra acostumbra a fallar, ya que tiene un límite dado por el MySQL de busqueda de palabras mayores o iguales a 4 carácteres, por lo que si buscasemos por ejemplo PHP no tendriamos resultado. Lo que haremos es mirar si la cadena que nos llega es de una sola palabra o de más de una, en caso de ser una haremos la búsqueda usando LIKE y si es más de una usaremos MATCH … AGAINST Buscador con paginación.
//Conectar con la base de datos,
//también podemos poner el ADODB
//Yo utilizo conexiones con código directamente aquí
include ("conexion_bd.php");
if ($p_busca!='')
{ if (!$num) $num=0;
//Separamos las palabras usando cada espacio como separador
//Hacemos la separación de la cadena a buscar
$cadena_buscada=explode(" ",$p_busca);
if (count($cadena_buscada)==1)
{
//Si solo hay una palabra usamos LIKE
$sql=" SELECT SQL_CALC_FOUND_ROWS titulo, texto
FROM noticiasLIKE '%".$p_busca."%' OR texto LIKE '%".$p_busca."%'
WHERE titulo
LIMIT ".$num.",10";
}
elseif (count($cadena_buscada)>1)
{
//Si hay más de una palabra usaremos MATCH AGAINST
$sql=" SELECT SQL_CALC_FOUND_ROWS titulo, texto, MATCH (titulo, texto)
AGAINST MATCH (titulo,AS Score FROM noticias
('".$p_busca."') texto) AGAINST ('".$p_busca."')
WHERE BY Score DESC LIMIT ".$num.",10";
ORDER
}
$rs = $db->Execute($sql);
if (!$rs) echo $conn->ErrorMsg();
else if ($rs->fields["id"])
{ while (!$rs->EOF)
{ echo $rs->fields["titulo"].'‘.$rs->fields[”texto”];
} $rs->MoveNext();
}
else
echo ‘No se han encontrado resultados correspondientes a su búsqueda.’;
//Paginación
$rs_cont=$db->Execute (”select found_rows() as total_filas”);
if ($rs_cont->fields[”total_filas”]>10)
{ for ($i=0; $i<$rs_cont->fields[”total_filas”] && $i<50; $i=$i+10)
{ $a++;
echo '[’.$a.’] ’;
} }
}