jueves, 9 de enero de 2014

El eclipse instala Pydev pero no lo muestra...

Un problema bastante común al instalar el Pydev en Eclipse (lo instale entrando por Help->Install new software y agregando "PyDev - http://pydev.org/updates"), aparentemente se había instalado todo bien, pero sin embargo después de reiniciado el Eclipse no se veía el Pydev...
Luego de romperme la cabeza buscando por internet veo que el problema es porque Pydev necesita tener java en version 7 para funcionar. 
Verifico mi Debian Wheezy y por defecto trae java 6, por suerte se puede instalar java 7 desde el gestor Synaptic, buscamos algo como java-7-openjdk-amd64 o algo y lo instalamos) después hacemos desde una terminal con root:

update-alternatives --config java

y ahí aparece un menú que permite elegir la versión de java por defecto y seteamos la 7.

Reiniciamos Eclipse y ¡eureca! apareció el pydev. 

lunes, 11 de noviembre de 2013

Cambiar timeout en php

Un programa en php que tiene que hacer muchas operaciones con la base de datos (lo cual tarda un tiempo considerable ya que hace un merge de una base grande casi completa) me tiraba el error...

Fatal error: Maximum execution time of 30 seconds exceeded in xxxx

Para arreglar el problema desde PHP le defino mas time_limit al script usando la función

set_time_limit(600);


... que limita el tiempo máximo de ejecución del script... acá más info: http://php.net/manual/es/function.set-time-limit.php

Cómo setear variables globales en MySQL

Desde línea de comandos (consola linux)...




#>mysql -uroot -e "show variables like '%timeout';" -p
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| connect_timeout            | 10    |
| delayed_insert_timeout     | 300   |
| innodb_lock_wait_timeout   | 50    |
| innodb_rollback_on_timeout | OFF   |
| interactive_timeout        | 28800 |
| net_read_timeout           | 30    |
| net_write_timeout          | 60    |
| slave_net_timeout          | 3600  |
| table_lock_wait_timeout    | 50    |
| wait_timeout               | 28800 |
+----------------------------+-------+ 
10 rows in set (0.00 sec)
#>mysql -uroot -e "SET GLOBAL net_read_timeout=600;" -p 
#>mysql -uroot -e "show variables like '%timeout';" -p
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| connect_timeout            | 10    |
| delayed_insert_timeout     | 300   |
| innodb_lock_wait_timeout   | 50    |
| innodb_rollback_on_timeout | OFF   |
| interactive_timeout        | 28800 |
| net_read_timeout           | 600   |
| net_write_timeout          | 60    |
| slave_net_timeout          | 3600  |
| table_lock_wait_timeout    | 50    |
| wait_timeout               | 28800 |
+----------------------------+-------+ 
10 rows in set (0.00 sec)

Listo!
:-P

miércoles, 25 de septiembre de 2013

Borrar muchos registros en CouchDB

Bueno, acá les dejo un script en Perl para borrar todos los registros obtenidos de una vista de CouchDB.


use strict;
use Store::CouchDB;

# database
my $couch_db = Store::CouchDB->new({ user => '<mi_user>', pass => '<mi_clave>' });
$couch_db->config({db => '<nombre_de_la_base>'});


my $mis_docs = $couch_db->get_view({  view => '<documento_de_diseño>/<nombre_de_la_vista>' });


while ( my ($key, $value) = each($mis_docs) ) {
    print "borrando registro id: $key\n";
    $couch_db->del_doc({id => $key}) or warn "err\n";
}

Espero que les sea útil.

martes, 10 de septiembre de 2013

CouchDB - Manejo de usuarios

Bueno, acá como crear usuarios, darles permisos y roles, etc...
Primeros, para el administrador, ni bien entramos deberíamos ponerle clave al administrador, eso de hace desde el futon (por defecto en http://localhost:5984/_utils/) y haciendo click en la parte inferior derecha, donde dice  " Welcome to Admin Party! Everyone is admin. Fix this" (en el Fix this :-). Y ahí nos pedirá Usuario y Clave.

Después deberíamos entrar en las bases de datos que tengamos y setearle miembros y administradores, ya que las bases que no tienen ningún miembro son públicas.
También si queremos deshabilitar el acceso anónimo a la base debemos entrar en Tools->Configuration (en la parte derecha del futon) y setear en true la variable require_valid_user.

Tipos de usuarios

En CouchDB se pueden setear tres tipos de usuario:

  • Adminsitradores: como vimos arriba, los usuarios admin del servidor tienen todos los privilegios.
  • Administradores de la base de datos: tienen todos los privilegios dentro de la base de datos de la que son administrador, pero no pueden acceder a otras bases ni crear o borrar otras bases ni la propia.
  • Y por último los miembros de la base de datos: pueden ver, crear y editar documentos en la base, excepto los de diseño.
Los Server Admin ya vimos como se setean. Los Database Administrators se setean en el objeto de seguridad de la base de datos, que se configura desde futon, entrando en la base y luego, en el botón "Security", en la parte superior, ahí me deja  ingresar los admins y los members de la base.
Hay que tener en cuenta que para que no permita acceso a cualquier usuario hay que ingresar al menos un valor en estos campos, ya que si dejamos por ejemplo los Roles vacíos va a dejar entrar a cualquiera, porque la base no tiene ningún rol asignado (lo mismo para miembros); entonces cualquiera podrá modificar documentos, aunque los documentos de diseño solo podrán ser modificados por administradores del servidor.

Usuarios

Para crear usuarios en nuestra base es muy facil, se crean como documentos en la base _users (si quisiéramos usar otro nombre se setea en la propiedad authentication_db de configuración). Con lo cual para crear el usuario pepe haríamos:

{
   "_id": "org.couchdb.user:pepe",
   "name": "pepe",
   "password": "password_de_pepe",
   "roles": ["DataEntry"
   ],
   "type": "user"
}
Para los usuarios, el _id debe comenzar con "org.couchdb.user:nombre de usuario" y nombre de usuario debe coincidir con name. En "roles" ponemos los roles a los que el usuario pertenece.

Roles


En nuestro servidor de base de datos podemos crear diferentes roles para los usuario. Como vimos en la creación de usuarios, le podemos dar al mismo usuario uno o más roles. Bueno, ahora entrando en nuestra base y yendo a "Security" (en el menú superior de Futon) podemos darle a esos roles permisos de administrador o miembro de la base; lo que hace que todos los usuarios que tengan el rol adquieran sobre nuestra base los permisos que le demos al rol.

martes, 3 de septiembre de 2013

Vistas en CouchDB


Para utilizar los datos de nuestra base CouchDB se utilizan vistas (views), que se escriben en JavaScript, las hay de dos tipos:
  • Las "vistas temporales" (temporary views) usadas mayormente en desarrollo ya que son muy lentas.
  • Las "vitas permanentes" que son documentos "especiales" de la base que se almacenan con el prefijo "_design"

Funciones de mapeo (Map Functions)

Cómo crear la vista en JavaScript... para explicar un ejemplo. Supongamos que tenemos documentos correspondientes a

{
   "_id": "320c8f17caa2698efdc307d7e6000b73",
   "type": "persona",
   "nombre": "Juan",
   "apellido": "Perez",
   "documento": 45678913
}

A los documentos les ponemos un type (o tipo) para identificarlos nosotros, bueno, si queremos una vista para ver las "personas" tenemos:

{
   "_id": "_design/personas",
   "_rev": "1-4530f2212bd4df41abeb18285a1ec450",
   "language": "javascript",
   "views": {
       "personas": {
           "map": "function(doc) {\n  if (doc.type == 'persona'){\n    emit(doc.documento, doc);\n  }\n}"
       }
   }
}

Analizando lo último, vemos que cree un documento con el id especial "_design/personas" (que lo identifica como documento de diseño), y que tiene una vista también llamada "personas" que tiene a su vez una función de mapeo.
Las funciones de mapeo se ejecutan para crear los índices de la base*1, se corren para todos los elementos de la misma. La función recibe doc, que es el documento de que se trate (se ejecuta una vez por cada documento), por eso lo primero que hacemos es ver si se trata de un documento de "persona", si es así corresponde emitir un resultado para le índice, que debe ser un par clave/valor, en este caso ponemos dni (doc.dni será la clave) y el documento mismo.*2



*1 La primera vez que usa una vista puede tardar en responder (dependiendo de la cantidad de datos que involucre) ya que es el momento en que se crea el índice mapeado (no cuando se graba la vista, sino la primera vez que se la invoca).
*2 Siempre debemos llamar a la función emit para envíe el par clave/valor para el índice.

Fuente: http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views

viernes, 30 de agosto de 2013

CouchDB desde perl, primeros pasos


CouchDB es una base de datos NOSQL de apache. Según leemo en Wikipedia "Se trata de una base de datos NoSQL que emplea JSON para almacenar los datos, JavaScript como lenguaje de consulta por medio de MapReduce y HTTP como API.1 Una de sus características más peculiares es la facilidad con la que permite hacer replicaciones.". ¡FANTÁSTICO!

Bueno, veamos como hacer desde perl para conectar a esta base y hacer algunas operaciones (simple ABM)...


# Para empezar usamos estos modulitos perl que baje de cpan
# Mas info dobre Store::CopuchDB en http://search.cpan.org/~norbu/Store-CouchDB-2.8/lib/Store/CouchDB.pm
use strict;
use Store::CouchDB;
use JSON;
# database
my $couch_db = Store::CouchDB->new();
# si tenemos la base con usuario y pass hacemos
# my $couch_db = Store::CouchDB->new( { user => '<mi user>', pass => 'mi pass', host => 'localhost o lo que sea' } );
 
 
 
 #creo una base de datos llamada 'pancho'
$couch_db->create_db('pancho');
print "base creada\n";

print "enter para seguir...";
<STDIN>;
#le configuro que use la base pancho
$couch_db->config({db => 'pancho'});
print "base seteada\n";

#Agrego un documento a mi base couchDB
my $doc = decode_json (' 
{
    "type":"persona",
    "nombre":"Felipe",
    "apodo":"Pipe",
    "telefonos":[
        {"tipo":"casa","numero":"123456789"}
        ]
}');
$couch_db->put_doc({doc => $doc});

print "Pipe agregado\nenter para seguir...";
<STDIN>;

$doc = decode_json (' 
{
    "type":"persona",
    "nombre":"Alberto",
    "apodo":"Beto",
    "telefonos":[
        ]
}');

my $inserted_doc = $couch_db->put_doc({doc => $doc});
print "Id del documento insertado (_id): $inserted_doc\n";
print "Beto agregado\nenter para seguir...";
<STDIN>;

$doc = decode_json (' 
{
    "type":"persona",
    "nombre":"Francisco",
    "apodo":"Pancho",
    "telefonos":[
        {"tipo":"casa","numero":"123456789"},
        {"tipo":"trabajo","numero":"987654321"},
        {"tipo":"celular","numero":"963258741" }
        ]
}');
$couch_db->put_doc({doc => $doc});

print "Pancho agregado\nenter para seguir...";
<STDIN>;
#leo un documento por su id
my $mi_doc = $couch_db->get_doc({id => $inserted_doc});
print "\n\nJSON:" . encode_json($mi_doc) . "\n\n";
print "Apodo de documento traido: " . $mi_doc->{apodo} . "*******\n";

$mi_doc->{apodo} = 'kuki';

#cambio el apodo
print "Apodo nuevo: " . $mi_doc->{apodo}  . "\n";
#actualizo el documento
$couch_db->put_doc({doc => $mi_doc});


#borro el documento
$couch_db->del_doc({id => $inserted_doc});

#borro la base

print "Registro modificado\nenter para seguir...";
<STDIN>;


print "\n";
1;






La instalación de CouchDB en windows es trivial, corre el instalador que se baja de http://couchdb.apache.org/ y listo.
yo para laburar perl desde windows uso DWIM Perl,l una genial distribución que tiene un perl basado en strawberry perl, muchos módulos de cpan preinstalados y el IDE Padre para programar en perl, que está muy copado.
Con estas herramientas instaladas para hacer el ejemplo de arriba solo debemos hacer
cpan -i JSON
cpan -i Store::CouchDB



Agregado 4/2014:
Luego de usar durante algún tiempo esta versión de Store::CouchDB de CPAN descubro que tengo un problema con los valores false y true, el problema viene de que perl no tiene false y true propiamente dichos (0 es false, etc) por lo que si quiero poner un valor false en CouchDB lo guarda como el string "false" (lo mismo con true).
Este problema se soluciona usando
Types::Serialiser::false
o
Types::Serialiser::true

También estoy usando una versión más reciente de Store::CouchDB, al momento la 3.6 que extrañamente no se encuentra en CPAN pero sí en github, podemos bajarla desde https://github.com/norbu09/Store-CouchDB.


jueves, 18 de julio de 2013

Usar funciones de PHP desde Perl fácil



A veces se hace necesario llamar a funciones de php desde un programa en perl. Eso es posible haciendo lo siguiente.

Creamos el archivo test.php con:

<?php

function testPHP($value){
    echo "Pruyeba111 de PHP:" . $value;
}

?>


Luego creamos el archivo perl que usara la función de php y nos queda así:

#!/usr/bin/perl
 
my $res = `php -r '
 
include_once "test.php";
 
testPHP ("\n\nTEEST2\n\n");
'
`;
print "\n\nResultado: $res";


Observar que la comilla en la línea de my $res= es una comilla simple que se usa en perl para ejecutar instrucciones de "afuera" del perl, es similar a escribir por consola o una llamada a la función "system(xxx)" de perl.