jueves, noviembre 10, 2011

Arduino Ethernet pro con linux

Luego de hacerle esa espantosa soldadura a mi placa arduino, me puse a hacer unos test para probar la funcionalidad del arduino ethernet pro. De hecho esos headers quedaron chuecos...

Aqui el primer problema es que uso Linux, y la libreria Ethernet del arduino no nos sirve (empieza a mandar basura). Buscando se recomienda cambiar esa librería por la Ethernet2.

Si solo la instalamos, en mi caso copiando los archivos a /usr/share/arduino/libraries/, nos van a salir errores de compilación, para resolverlos editamos el archivo Server.cpp y sustituimos #include "Ethernet.h" por #include "Ethernet2.h", el siguiente paso es borrar los archivos Print.cpp y Print.h

Para probarlo simplemente hay que sustituir en nuestros proyectos Ethernet.h por Ethernet2.h

#include 

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 10, 198, 0, 2 };
byte server[] = { 10, 198, 0, 1 }; //My machine host

Client client(server, 8080);

const int buttonPin = 7; // the number of the pushbutton pin
const int ledPin = 3; // the number of the LED pin

// Variables will change:
int lastButtonState = LOW; // the previous reading from the input pin

void setup() {
Ethernet.begin(mac, ip);
Serial.begin(9600);

//Esperamos a que se inicie la Ethernet
delay(1000);

Serial.println("connecting...");


pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
}

void reacciona(){
if (client.connect()) {
Serial.println("connected");
client.println("GET /Robotina/escucha/escucha HTTP/1.0");
client.println();

if (client.available()) {
for (int i; i<100; i=0) {
char c = client.read();
Serial.print(c);
}
}
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
}
} else {
Serial.println("connection failed");
} }
void loop() {
int reading = digitalRead(buttonPin);
if (reading == HIGH && lastButtonState != reading) {
reacciona();
}
if (lastButtonState!= reading) {
lastButtonState = reading;
}
digitalWrite(ledPin, lastButtonState);
}


Y este seria mi esquema:


martes, julio 05, 2011

cd suffle

Hoy me hicieron el día: tenía tiempo que no encontraba una opción tan oscura y a la vez tan útil de un comando que uso diario, a todas horas y del cual pensaba ya no sacar más provecho, el hecho en cuestion es cd shuffle...

Cabe aclarar que sólo funciona con ksh, si estas con bash no funcionará... Pasemos al pedazo del man ksh que nos interesa:

cd [ -LP ] [ arg ]
cd [ -LP ] old new
..explicaciones mas, explicaciones menos...
The second form of cd substitutes the string new for the string old in the current directory name, PWD, and tries to change to this new directory.
..explicaciones mas, explicaciones menos...


Y a la demostracion:

[root@macuile .gnome2]# ksh
# echo $SHELL

/bin/bash
#Nota: no tengo idea de donde guarda ksh el shell utilizado actualmente
# como podrán darse cuenta no se borró el SHELL anterior
# echo $$
12330
# ps -ef | grep $$
root 12330 12277 0 22:53 pts/0 00:00:00 ksh
root 12339 12330 0 22:53 pts/0 00:00:00 ps -ef
root 12340 12330 0 22:53 pts/0 00:00:00 grep 12330
#Nota: con esto nos aseguramos de que sea ksh
# cd /home/db2inst1/.gnome2
# cd db2inst1 miguel

/home/miguel/.gnome2
# pwd
/home/miguel/.gnome2
#Nota: magia, nos cambiamos de directorio
[root@macuile .gnome2]# echo $SHELL
/bin/bash
[root@macuile .gnome2]# pwd
/home/db2inst1/.gnome2
[root@macuile .gnome2]# cd db2inst1 miguel
-bash: cd: db2inst1: No such file or directory
[root@macuile .gnome2]# mkdir db2inst1 miguel
[root@macuile .gnome2]# cd db2inst1 miguel
#Nota: A mi parecer este comportamiento es peor que no hacer nada y fallar
[root@macuile db2inst1]# pwd
/home/db2inst1/.gnome2/db2inst1
[root@macuile db2inst1]# mkdir miguel
[root@macuile db2inst1]# cd ..
[root@macuile .gnome2]# cd db2inst1 miguel
#Nota: sería interesante que hubiera entrado hasta miguel, no hubo suerte
[root@macuile db2inst1]# pwd
/home/db2inst1/.gnome2/db2inst1
[root@macuile db2inst1]# ls -l
total 4
drwxr-xr-x 2 root root 4096 Jul 5 23:20 miguel


miércoles, febrero 02, 2011

Sobre la decompilación o la reingeniería


De estos requerimientos que nadie quiere hacer y una vez hecho ya no se ocupan, la cosa va mas o menos asi:

Hay varios appserver, cada uno con sus app, cada app contiene un jar (modelo.jar) que se ocupa, entre otras cosas, para saber
si la app se encuentra en produccion, desarrollo o pruebas. Muy listo el truco, la app se da cuenta mediante el hostname de la
maquina donde esta alojada la app. Erroneamente se pensaría que el modelo.jar es el mismo para todas las app, pero no, hay 260
y tantos jars diferentes y de los cuales yo no tenía ni idea de como funcionaban.

solucion:
Agarra todos los jar decompilar la clase que hace referencia al hostna, compilarla con el nuevo hostname y actualizar el jar...
Y para esto nuestro buen amigo sed viene al rescate.

1 #!/bin/ksh -
2 #===============================================================================
3 #
4 # FILE: reemplazar_ambiente.sh
5 #
6 # USAGE: ./reemplazar_ambiente.sh
7 #
8 # DESCRIPTION:
9 #
10 # OPTIONS: ---
11 # REQUIREMENTS: ---
12 # BUGS: ---
13 # NOTES: ---
14 # AUTHOR: Miguel Angel Huerta Gonzalez
15 # COMPANY:
16 # CREATED: 26/01/2011 12:35:06 p.m. Hora estándar central (México)
17 # REVISION: ---
18 #===============================================================================
19
20 set -o nounset # Treat unset variables as an error
21
22 JDEC=/home/user/jode-1.1.2-pre1.jar
23
24 #A_REEMPLAZAR="/app-2709/webapps/WEB-INF/lib/modelo.jar \
25 #/app-2709/webapps1/WEB-INF/lib/modelo.jar \
26 #/app-2709/webapps3/WEB-INF/lib/modelo.jar \
27 #/app-2709/webapps4/WEB-INF/lib/modelo.jar"
28
29 for MODELO in $A_REEMPLAZAR ; do
30 echo "=======================$WEBAPP============================="
31 ls -l $MODELO
32 cp $MODELO .
33 WEBAPP=$(echo $MODELO | awk -F/ '{printf "%s/%s\n", $6,$7}')
34 mkdir -p respaldo/$WEBAPP
35 cp $MODELO respaldo/$WEBAPP
36 AMBIENTE=$(jar tf modelo.jar | grep Ambiente)
37 echo $AMBIENTE
38 mkdir -p $(dirname $AMBIENTE)
39 java -cp $JDEC jode.decompiler.Main -c modelo.jar com.app.modelo.apConfig.Ambiente > Ambiente.java
40 FILE=$(dirname $AMBIENTE)
41 sed '
42 /apphostname.*PRODUCCION/ i\
43 ambientes.put("apphostnamenew".toUpperCase(), PRODUCCION);
44 ' Ambiente.java > Ambiente2.java
45 mv Ambiente2.java Ambiente.java
46 javac -classpath modelo.jar Ambiente.java
47 mv Ambiente.class $(dirname $AMBIENTE)/
48 jar uf modelo.jar $AMBIENTE
49 mkdir -p output/$WEBAPP
50 #cp modelo.jar output/$WEBAPP
51 cp modelo.jar $MODELO
52 echo "=======================$WEBAPP============================="
53 done
54

domingo, enero 16, 2011

Sobre el spam y las cadena

Como no todo lo que esta por internet es cierto, me comentaron de una cadena muy curiosa, la cosa iba más o menos asi:

Bla bla bla, este mes es especial porque tiene 5 Lunes, 5 Sábados y 5 Domingos, y esto solo se repite cada 834 años... bla bla bla si no mandas esto tendras 5 años de perdición...

Y como todos los fines de semana termino haciendo muchas cosas menos las que tenía que hacer, he aqui que esta cadena es una mentira...

#!/bin/bash - 

ANIO=1176
while [ $ANIO -lt 2011 ]; do
ANIO=$(($ANIO+1))
if [ "$(cal 1 $ANIO|tail -n+3)" == "$(cal|tail -n+3)" ]; then
echo "otro año maravilloso $ANIO"
fi
done


$ ./prueba_cadena.sh otro año maravilloso 1177
otro año maravilloso 1183
otro año maravilloso 1194
...

otro año maravilloso 1994
otro año maravilloso 2000
otro año maravilloso 2005
otro año maravilloso 2011
$


Pues parece que tenemos bastantes años más para pedir nuestros deseos...


$ cal 1 2005
Enero 2005
do lu ma mi ju vi sá
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
$ cal
Enero 2011
do lu ma mi ju vi sá
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
$


En fin, es una estupidez haberlo comprobado, pero me sirve para repasar el scripting.

Y entre otros temas, opencv; cuando me siento frente a mi lap siento que alguien me observa, y asi es, el lente de la webcam que viene inscrutada por defecto (en estricto sentido el defecto), pero se le puede sacar algun provecho..



Y la cosa funciona, he modificado un poco un ejemplo que viene por ahi lkdemo.py y la cosa anda, se puede mover el mouse con las manos, y ahi estoy, falta hacer algo como un lenguaje para interactuar con la pantalla...

miércoles, enero 05, 2011

Todo es un archivo

Todo es un archivo... Es una de las cosas que se aprende en UNIX/Linux, que todo es un archivo, pero hay diferentes tipos de archivos, revisemos man test:

-b FILE
FILE exists and is block special
-c FILE
FILE exists and is character special
-d FILE
FILE exists and is a directory
-f FILE
FILE exists and is a regular file
-h FILE
FILE exists and is a symbolic link (same as -L)
-S FILE
FILE exists and is a socket

Claro, nada es tan simple como parece y hay muchos tipos de archivos :-), y con este preámbulo entremos en materia...
Si has usado algún comando y le has pasado la entrada estándar, por ejemplo cat < file.in, se te habrá ocurrido hacer lo mismo para tus scripts. Me llevo un tiempo encontrar una solución para este problema:

if [ ! -c /proc/$$/fd/0 ]
then
MENSAJE=$(cat -)
else
MENSAJE=""
fi


Cada proceso crea dentro de /proc/PID/fd/ la entrada estándar 0, salida estándar 1, y error estándar 2, lo que hacemos es comprobar que la entrada estándar del shell no sea un fichero de carácter especial (en este caso el teclado). Podemos probar que tipo de archivo es con estos comandos:


$ file /dev/fd/0
/dev/fd/0: symbolic link to `/dev/pts/0'
$ file /dev/pts/0
/dev/pts/0: character special

Se me hizo más fácil comprobar solo que no sea de tipo "character special", pero bien pudiéramos solo aceptar archivos normales:

if [ -f /proc/$$/fd/0 ]

$(cat -) lee la entrada estándar, si no hiciéramos la comprobación se quedaría esperando a que tecleáramos ctrl + d

Ya con esto podemos invocar nuestro script de estas dos formas sin problemas:

script.sh < archvio.txt
script.sh

a mi me sirvió para esto:

cat <<EOF | (cat -; for i in $@; do uuencode $i $(basename $i);done ) | mailx -s "$SUBJECT" $CORREO
$MENSAJE
EOF
Cosa que requiere más explicación y muchos más conceptos que no creo que llegue a explicar :-)...

nota: $$ nos devuelve el pid del programa en ejecución. Si son curiosos hagan un ls -l /proc/$$


domingo, septiembre 05, 2010

SQL antipatterns

Termine de leer otro libro, SQL Antipatterns, veamos. Ultimamente han proliferado los ORM, como hibernate, y con el surgimiento de ruby on rails, el patrón de ActiveRecord; ¿qué es lo que esto ha ocacionado?, pues un completo desperdicio de los motores de base de datos, y un aumento de antipatrones en el diseño de la DB. Sin mas con este libro te sorprenderás de lo fácil que es hacer queries y hacerlos bien, nunca he entendido como es que se prefiere la complejidad de hsql, el no entender que SQL es un lenguaje declarativo es de los peores errores de un programador, a SQL le dices que es lo que quieres, no las instrucciones de como hacer lo que quieres.

Es un libro ligero, de una buena lectura, que si tienes algo de experiencia en diferentes proyectos, te darás cuenta que tan recuerrente son estas malas prácticas y cuando leas la solución verás que era muy fácil no caer en ellas.

Aqui algunas anotaciones de mi kindle:

==========

SQL Antipatterns

- Highlight Loc. 1699-1704 | Added on Sunday, August 08, 2010, 04:35 PM

SELECT * FROM Comments AS c LEFT OUTER JOIN (BugsComments JOIN Bugs AS b USING (issue_id)) USING (comment_id) LEFT OUTER JOIN (FeaturesComments JOIN FeatureRequests AS f USING (issue_id)) USING (comment_id) WHERE c.comment_id = 9876;

==========

SQL Antipatterns

- Highlight Loc. 2233-36 | Added on Sunday, August 08, 2010, 07:16 PM

IEEE 754 represents floating-point numbers in a base-2 format. The values that require infinite precision in binary are different values from those that behave this way in decimal. Some values that only need finite precision in decimal, for instance 59.95, require infinite precision to be represented exactly in binary. The FLOAT data type can't do this, so it uses the closest value in base-2 it can store, which is equal to 59.950000762939 in base-10.


==========

SQL Antipatterns

- Highlight Loc. 4777-78 | Added on Monday, August 30, 2010, 07:48 AM


Mitch Ratcliffe said, "A computer lets you make more mistakes faster than any other human invention in human history…with the possible exception of handguns and tequila."

==========

SQL Antipatterns

- Highlight Loc. 4822-26 | Added on Monday, August 30, 2010, 07:55 AM

But do the math: if you generate unique primary key values as you insert 1,000 rows per second, 24 hours per day, you can continue for 136 years before you use all values in an unsigned 32-bit integer. If that doesn't meet your needs, then use a 64-bit integer. Now you can use 1 million integers per second continuously for 584,542 years. It's very unlikely that you will run out of integers!

==========

SQL Antipatterns

- Highlight Loc. 5037-40 | Added on Monday, August 30, 2010, 10:56 PM

Even among developers who accept best practices when developing application code, there's a tendency to think of database code as exempt from these practices. I call this antipattern Diplomatic Immunity because it assumes that the rules of application development don't apply to database development.

==========

SQL Antipatterns

- Highlight Loc. 5537-38 | Added on Wednesday, September 01, 2010, 07:14 AM

Young man, in mathematics you don't understand things. You just get used to them. John von Neumann

==========

SQL Antipatterns

- Highlight Loc. 5549-51 | Added on Wednesday, September 01, 2010, 07:16 AM

This term relational doesn't refer to relationships between tables. It refers to the table itself, or rather, the relationship between columns within a table. In a way, it refers to both.


lunes, julio 26, 2010

¿ocupa o no el indice?

Este es uno de los blogs que me gusta seguir http://www.depesz.com/ habla sobre todo de queries sql y esas cosas, pero todo basado en postgres. Me gusta seguirlo y hacer lo posible por imitar sus problemas pero en db2, he aqui un intento:HOW TO ORDER BY SOME RANDOM – QUERY DEFINED – VALUES?

Esta funcion viene por defecto en postgres y se ocupa demasiado, te da muchas ventajas no la eh optimizado ni nada, y por ahi pienso que se puede usar metaprogramación para que quede más rápida, pero ahí va.

CREATE OR REPLACE FUNCTION generate_series (ini integer, fin integer, inc integer)
RETURNS TABLE (val integer)
LANGUAGE SQL
READS SQL DATA
NO EXTERNAL ACTION
DETERMINISTIC
RETURN
with dummy(id) as (
select generate_series.ini from sysibm.sysdummy1
union all
SELECT id + generate_series.inc FROM dummy WHERE id < generate_series.fin
)
select id from dummy@

Las pruebas de rigor

select * from TABLE(generate_series(1,20,2)) as X@
--SELECT substr(funcschema, 1, 12) as funcs, substr(funcname, 1, 30) as func from syscat.functions ORDER BY 1,2 @

Empezamos con el tutorial.

CREATE TABLE test_data (
id INT NOT NULL PRIMARY KEY, --te pide afuerza el not null
codename VARCHAR(254)
)@

SELECT * FROM test_data @

INSERT INTO test_data (id, codename)
SELECT i.val, 'codename for:' || i.val
FROM TABLE(generate_series(1,100,1)) as i @ -- pequeño truco, hay que poner TABLE si no no jala

Y este es el query que nos interesa, muy sencillo, pero me trae sus consecuencias.

SELECT  id, cast(codename as varchar(15)) FROM test_data WHERE id IN (3, 71, 5, 16);@
ID 2
----------- ---------------
3 codename for:3
71 codename for:71
5 codename for:5
16 codename for:16
* 4 row(s) fetched, 4 row(s) output.
* Elapsed Time is: 0.001058 seconds

Y sorpresa, los valores nos los da ya ordenados. No hay que hacer más trucos, pero a mi experiencia esto esta mal.


SELECT id, cast(codename as varchar(15)) FROM test_data WHERE id IN (71, 3, 5, 16);@
ID 2
----------- ---------------
71 codename for:71
3 codename for:3
5 codename for:5
16 codename for:16
* 4 row(s) fetched, 4 row(s) output.

Pequeñas variaciones y hace lo mismo. Ahora bien, ¿esto esta bien? segun yo no, los datos deberian de aparecer de acuerdo al orden de inserción, si no abría que asumir que la db esta haciendo algo que no le hemos indicado, en este caso ordenar. Pero el error sigue siendo otro, en esta consulta no se ocupa el indice
De Miguel Angel Huerta Gonzalez



SELECT id, cast(codename as varchar(15)) FROM test_data WHERE id IN (71, 3, 5, 16, 27, 19, 2);@
ID 2
----------- ---------------
2 codename for:2
3 codename for:3
5 codename for:5
16 codename for:16
19 codename for:19
27 codename for:27
71 codename for:71
* 7 row(s) fetched, 7 row(s) output.
* Elapsed Time is: 0.050610 seconds


Y aqui esta lo que esperamos!!!, porque lo hizo? porque hay más datos?, si parece que ocupa el indice solo cuando hay muchos datos. Este es un comportamiento normal, las base de datos solo van al índice cuando hay que ir al índice.

De Miguel Angel Huerta Gonzalez


Imaginemos el seq scan, va comparando 1 por 1, y es por esto que los datos nos los da como aparecen en el IN. Cuando va al indice, rearma la consulta y los datos no los trae de acuerdo a como aparecen en el ínce.

Realizé otra prueba en sqlite, donde solo inserte 10 datos y ahi lo tienen, los datos aparecen en el orden del indice y no en el de insercion como pensaba...


sqlite> SELECT * FROM test_data WHERE id IN (3, 1, 5, 6);
1|codename for 1
3|codename for 3
5|codename for 5
6|codename for 6
sqlite>

-- Un select sin nada si nos da por orden de insercion.
sqlite> SELECT * FROM test_data ;
10|codename for 10
9|codename for 9
8|codename for 8
7|codename for 7
6|codename for 6
5|codename for 5
4|codename for 4
3|codename for 3
2|codename for 2
1|codename for 1

-- Mis intentos de sacar un explain en consola no prosperaron
-- EXPLAIN PLAN SET QUERYNO = 13
-- EXPLAIN PLAN SET QUERYNO = 1 FOR SELECT * FROM test_data WHERE id IN (3, 71, 5, 16);

jueves, julio 22, 2010

Land the tech job you love - crítica

Excelente libro, me hubiera encantado leerlo unos cuantos meses antes de tomar la desición de dejar mi trabajo, hay muchas cosas que hay que estar haciendo continuamente, se tenga o no trabajo. Les dejo los consejos que he tomado de este libro:

Hacer un CV.

Hay que hacerlo, eh irle añadiendo cosas, recomienda usar txt (yo tambien), igual y aprendes VIM o EMACS y ya sería algo nuevo que añadir a tu CV, hay que hacerlo cada 6 meses, si no tienes nada que añadir es un buen indicativo de que te hace falta un cambio y de que te has estancado en tu carrera.

Puedes ver el CV del autor y darte una idea de como tener el tuyo

Tener un portafolio.

Tienes código que te den ganas de imprimir, hazlo y en una entrevista tendrás la oportunidad de mostrarlo. Lo mismo pasa con los diagramas de base de datos, que tal el esquema de la red que administras o planes de proyectos. Todo eso cuenta y te dará ventaja sobre otros candidatos.

Contactos.

Tener una red de contactos a los cuales pedir ayuda, por ejemplo, en mi ultimo puesto estuve trabajando con varios consultores, de los cuales no me quede ninguna referencia, si las tuviera no dudaria en enviarles un mail y preguntar si me pueden recomendar con RH o algo asi. En nuestra carrera nos gusta ayudar porque se tiene que trabajar muchas veces en equipo, estamos acostumbrados a preguntar y responder dudas tecnicas, etc. Asi que no creo que lo tomen a mal si es que pides ayuda de este tipo. Y definitivo no lo tomes a mal si recurren a ti y trata de indicarles la ruta correcta.

Buscar siempre tu proximo trabajo:

Esto te ayudará a ver como se esta moviendo el mercado, si las tecnologias que dominas estan arcaicas o ya nadie las ocupa, te dará una idea sobre que skills tienes que estudiar y además te darás idea de como se estan moviendo los salarios. Si crees que estas cometiendo algo desleal al buscar trabajo te dejo estas fraces que rescato del libro:

"First, your primary loyalty has to be to yourself, not to your organization"

"Second, I guarantee you that your company has no loyalty to you"

Haz estas sencillas preguntas, y si te falta algo empieza a trabajar en ello:

  • ¿Tu CV esta actualizado?
  • ¿Tus habilidades siguen siendo competitivas con el resto del mercado?
  • ¿Tienes al menos 5 personas a las que puedas pedir ayuda para encontrar trabajo?
  • ¿Tienes al menos 3 personas a las que puedas dar como referencia en un trabajo?
Por último: Aprender aprender, siempre tratar de aprender algo nuevo y escribir hacerca de ello. Si crees que puedes pasar un examen de certificación, hazlo.


Ficha tecnica:
by Andy Lester
280 pages, Jun 2009
ISBN: 978-1-93435-626-5


jueves, julio 15, 2010

vim and db2

Una de las herramientas que más me gusta y la que más me critican es el uso de VIM, pero estoy acostumbrado a usar máquinas poco potentes (mi actual máquina es una mini acer aspire one) y el ahorro de memoria es muy apreciado para mi.

Actualmente me estoy especializando en db2 y como sabrán todas sus herramientas visuales de administración corren en java (malo para la memoria) así que ¿por qué no integrar db2 y vim?. Y como le pasa a mi amigo Toño, con casi todas sus buenas ideas, ya esta inventado. No tan solo se puede conectar a db2, sino que soporta varias bases de datos, el plugin de vim es dbext.vim, después de leer la documentación y seguir el :h db2ext-tutorial, me tiraba el siguiente error:

Connection: T(DB2) D(sample) at 22:28

*** Invalid argument(s) for command line option

*** For option "-s"

* Type 'db2batch -h' for help.

/bin/bash: -f: no se encontró la orden

To change connection parameters:

:DBPromptForBufferParameters

Or

:DBSetOption user|passwd|dsnname|srvname|dbname|host|port|...=<value>

:DBSetOption user=tiger:passwd=scott

Last command(rc=127):

db2batch -q off -s off-d sample -l ; -f /tmp/vZbICSm/dbext.sql

Last SQL:

SELECT id FROM customer;

Grave error, pero hay que fijarnos bien en el comando que ejecuta:

db2batch -q off -s off-d sample -l ; -f /tmp/vZbICSm/dbext.sql

Que tiene de malo, varias cosas:

-s off-d sample :No hay espacio entre off-d

-l ; :en linux ; tiene un significado especial asi que hay que encerrarlo entre "" o de plano quitarlo

Leyendo un poco el código fuente del plugin .vim/autoload/dbext.vim, vemos la falla, la cual se localiza en las variables:

g:dbext_default_DB2_cmd_options.'':'-q off -s off'

g:dbext_default_DB2_cmd_terminator.'':';'

Así que para no aburrirles tanto ejecutamos en vim:

:let g:dbext_default_DB2_cmd_options = '-q off -s off '

:let dbext_default_DB2_cmd_terminator = ''

y ya tendremos funcionado nuestro plugin.

Ver video con la nostalgia de mis tecladazos!!!

Edit: no se pudo subir el audio...

martes, julio 06, 2010

Error CLI0622E

Al momento de instalar DB2 express - C no podía acceder a las herramientas gráficas, como el command center (db2cc), debido al error cli0622e:

db2inst1@macuile:~$ db2 ? CLI0622E

CLI0622E Error accessing JDBC administration service extensions.

Casi toda la ayuda en google dice que el error es debido a que no tenemos los driver JDBC en nuestro directorio $inst/sqllib, pero en mi caso si estaban todos.

El problema huele a cosa de java, y lo es:

db2inst1@macuile:~$ db2 get dbm cfg | grep JDK_PATH
Java Development Kit installation path (JDK_PATH) = /usr/lib/jvm/java-6-sun/

No recuerdo cual era mi JDK_PATH por defecto, pero tampoco funcionaba con eso
¿por que?
Supongo que porque debian no está soportado tal cual en la instalación, se quedan muchas rutas por defectos y alguno que otro problema concerniente a esta lucha entre las distribuciones. Además de que no todas las implementaciones del JRE son iguales, algo habrá hecho IBM con es jdk

La solucíon, encontrar el JRE que instala DB2, en mi caso
/home/ibm/db2/V9.7/java/jdk32/

Ejecutar el siguiente comando:
$ db2 update dbm cfg using JDK_PATH /home/ibm/db2/V9.7/java/jdk32/

Esto tendría que hacerse por instancia.

Datos:
db2inst1@macuile:~$ db2level
DB21085I Instance "db2inst1" uses "32" bits and DB2 code release "SQL09071"
with level identifier "08020107".
Informational tokens are "DB2 v9.7.0.1", "s091114", "IP23033", and Fix Pack
"1".
Product is installed at "/home/ibm/db2/V9.7".

miguel@macuile:~/Desktop$ uname -a
Linux macuile 2.6.32-3-686 #1 SMP Thu Feb 25 06:14:20 UTC 2010 i686 GNU/Linux

miguel@macuile:~/Desktop$ cat /etc/debian_version
squeeze/sid