Mostrando entradas con la etiqueta código. Mostrar todas las entradas
Mostrando entradas con la etiqueta código. Mostrar todas las entradas

lunes, 17 de marzo de 2025

Migrar tweets a BlueSky

  •  Exportar datos de Twitter (X)

Una vez solicitado se recibirá un email (menos de 24 horas) avisando que los datos están listos.

    1. Tener instalado NODE
    2. Generar una contraseña en Bluesky para utilizarla con el programa de migración. Ir a configuración - Privacidad y Seguridad - Contraseñas de App - Añadir una nueva.
    3. Una ver copiado el repositorio instalar los paquetes desde la terminal: npm install
    4. Ejecutar el programa. Ejemplo: node app.js --archive-folder /Users/nombreusuario/carpeta-importada-twitter --bluesky-username jp-romero.bsky.social --bluesky-password qwer-asdf-zxccv-1234 --twitter-handles _juanpa --ignore-video-errors

jueves, 22 de septiembre de 2022

¿Cómo ocultar botones de la barra de menú de Autodesk Forge?

 



Podemos empezar imprimiendo en consola la variable toolbar para ver los valores de controls. Los cuales son las secciones en las que se divide la barra.


Podemos ver que  cada sección se llama:

  • navTools
  • measureTools
  • modelTools
  • settingsTools
Y si expandimos una de ellas podemos ver que dentro encontramos controls donde está cada botón de la sección. 


Es decir, si queremos ocultar la cámara de la primera sección tenemos que hacer algo como:


this.viewer.toolbar.getControl('navTools').removeControl('toolbar-cameraSubmenuTool');

Vamos a ocultar algunas más y ver el resultado.

this.viewer.toolbar.getControl('settingsTools').removeControl('toolbar-propertiesTool');
this.viewer.toolbar.getControl('settingsTools').removeControl('toolbar-modelStructureTool');
this.viewer.toolbar.getControl('settingsTools').removeControl('toolbar-settingsTool');
this.viewer.toolbar.getControl('modelTools').removeControl('toolbar-explodeTool');




domingo, 24 de febrero de 2019

Montar un disco para compartir con Samba en Ubuntu server

Resultado de imagen de share "files" samba

Formatear disco

Consultar particiones y sistemas de fichero
sudo lsblk -fm

Otra forma de consultar los discos y particiones
sudo fdisk -l

Para gestionar particiones se indica el disco y se opera con las opciones dadas («m» para ver opciones)
sudo fdisk /dev/sdb

Para crear una partición se presiona «d» y se sigue la guía.


Formatear la partición
sudo mkfs.ext4 /deb/sdb1

*Tienen que estar desmontado. La primera vez que se haga lo estará. Pero si se ha montado y se quiere desmontar un disco:
sudo umount /dev/sdb1

*Si está ocupado no se puede desmontar el disco, se puede consultar qué procesos lo usan previo desmontaje:
sudo fuser -vm /dev/sdb1

En el ejemplo, estaba siendo usado por el proceso de Samba, así que detuve Samba y se pudo desmontar. Sino tocaría matar/parar procesos, o forzar el desmontaje.

*Si se da formato NTFS al disco no se puede aplicar la política unix de usuario/grupo a los ficheros impidiendo la gestión por usuario al compartir ficheros

Montar disco

Crear carpeta donde alojar el disco
sudo mkdir /media/data

Montar el disco en la carpeta
sudo mount /dev/sdb1 /media/data

Modificar el fichero fstab para que la configuración quede guardada
sudo nano /etc/fstab

En el ejemplo:
/dev/sdb1 /media/data ext4 defaults 1 2

Instalación y configuración de Samba (Ubuntu server 16.04)

Si estamos aquí es porque queremos compartir ficheros. Samba se instaló en Ubuntu y se accede desde Windows, Mac OS X, otros Linux. El proceso indica cómo hacer una carpeta de acceso general y otra de uso bajo usuario y contraseña.

Si no estuviera instalado samba se instala
sudo apt install samba

Se edita el archivo: /etc/samba/smb.conf

Se descomenta/modifica la línea
wins support = yes
net bios = MySERVER #nombre del equipo en la red

Y al final del fichero se añade la configuración de cada carpeta a compartir:
[publica]
path = /media/data/folderpublic 
browsable = yes 
guest ok = yes 
only guest = no 
read only = no 
create mask = 0777 
directory mask = 0777 
public = yes

[privada] 
path = /media/data/folderpriv 
browsable = yes 
guest ok = no 
read only = no 
create mask = 0770 
directory mask = 0770
  • path ubicación de la carpeta a compartir
  • browsable si es navegable desde el Explorador de Windows
  • guest si permite la conexión de forma anónima sin usuario y contraseña
  • read only si solo es de lectura o se permite escritura
  • create mask permisos con los que se van a crear los nuevos ficheros
Se tienen que tener la carpeta creada con los permisos adecuados
sudo mkdir -p /media/data/folderpublic 
sudo mkdir -p /media/data/folderpriv

Crear usuario linux y grupo a utilizar para acceso a la carpeta privada
sudo useradd userpriv
sudo groupadd grouppriv

Se asigna el grupo al usuario
sudo usermod -g grouppriv userpriv

*Si se quiere añadir el usuario a grupos adicionales
sudo adduser userpriv otrogrupo

Se agrega como usuario samba
sudo smbpasswd -a userpriv

Listar usuarios samba
pdbedit -L

Si se quiere eliminar un usuario
sudo smbpasswd -x userpriv

Aplicar permiso de forma recursiva al directorio y subdirectorios (por si los hubiese)
sudo chmod -R 775 /media/data/folderpublic
sudo chmod -R 775 /media/data/folderpriv

Cambiamos grupo a la carpeta
sudo chown -hR root:grouppriv /media/data/forderpriv
sudo chown -hR nobody:nogroup /media/data/folderpublic

Reiniciar samba tras los cambios
sudo /etc/init.d/samba restart

*Para Samba (en caso de necesitar)
sudo /etc/init.d/samba stop

*Iniciar Samba (en caso de necesitar)
sudo /etc/init.d/samba start

Eliminar credenciales de Windows para conexiones compartidas

Cuando estamos viendo carpetas compartidas Windows ya suele almacenar credenciales y como solo permite una a la vez si luego queremos acceder a otro recurso con credenciales diferentes tendremos problemas de acceso, para ello lo más rápido eliminamos credenciales guardadas.

- Presionar las teclas Windows + R
- Escriben en la ventana de Ejecutar: cmd
- En la ventana que se abre escribir: net use * /del
- Escriben una ese «S» para confirmar la eliminación de entradas en caso de existir.
- Pueden cerrar la ventana

Cerrar todas las ventanas del Explorador de Windows que están viendo recursos de red.

Ahora en la ventana de Ejecutar (Windows+R) escribir
rundll32.exe keymgr.dll, KRShowKeyMgr

En la ventana que se abre se elimina las credenciales que acceden a recursos compartidos (o se configura una para la conexión que queremos, en mi caso a 192.168.1.5). En el ejemplo no influye ni DriveFS ni GitHub.


Reiniciar el servicio de credenciales

Una vez hecho esto se podrá iniciar sesión para acceder al recurso. Si se almacenan las credenciales el acceso será directo.







viernes, 15 de febrero de 2019

MySQL: crear índice único y no único

Una PRIMARY KEY crea un índice único asociado al campo que es clave primaria, además es NOT NULL por defecto, y por tabla se tiene una sola clave primaria.
Cuando queremos que un campo o varios sean únicos entonces creamos una constraint UNIQUE y si queremos que sea un índice no único lo declaramos como KEY pero no en la misma línea del campo porque significaría que declaramos una PRIMARY KEY, y no es lo que queremos.

create table test(
    clave_primaria    int unsigned not null,
    clave_unica       varchar(128) default null,
    clave_nounica     varchar(128) default null,
    constraint pk_test_claveprimaria primary key(clave_primaria),
    constraint uq_test_claveunica unique(clave_unica),
    key(clave_nounica)
);





Se ha utilizado
-MySQL Ver 14.14 Distrib 5.7.23, for Win64

domingo, 19 de agosto de 2018

Moodle: Enviar email como HTML




  • Se añade un quinto valor a la función email_to_user que corresponde con el mensaje en HTML.
Archivo en el que reemplazar texto: moodle/lib/moodlelib.php
Texto a buscar: email_to_user($user, $supportuser, $subject, $message);
Se reemplaza por: email_to_user($user, $supportuser, $subject, $message, $message);
  • Se elimina la función html_to_text
Archivo: moodle/message/lib.php
Texto a buscar: $eventdata->fullmessage = html_to_text($eventdata->fullmessagehtml);
Se reemplaza por: $eventdata->fullmessage = $eventdata->fullmessagehtml;
  • Dónde escribir el texto HTML:

- Personalizar email auto-matriculación en curso:
Cuando el usuario se auto-matricula en un curso.
Administración del curso/Usuarios/Método de matriculación/Auto-matriculación (estudiante)
Rellenar con el texto HTML en la casilla «Mensaje personalizado de bienvenida» y guardar.

- Personalización email alta usuario manual:
Cuando el administrador lo añade de forma manual al sitio, tanto de forma individual como en subida con fichero CSV.
Administración del sitio/Idioma/Personalización idioma
core: moodle.php
string: newusernewpasswordtext
Escribir el texto HTML en la casilla «Traducción local personalizada» y guardar los cambios del paquete de idioma.



- Personalizar email de restablecimiento de contraseña:
Cuando el usuario ha olvidado su usuario o contraseña, y busca por nombre de usuario o contraseña se le envía el e-mail de restablecimiento.
Administración del sitio/Idioma/Personalización idioma
core: moodle.php
string: emailresetconfirmation
Escribir el texto HTML en la casilla «Traducción local personalizada» y guardar los cambios del paquete de idioma.

- Personalizar email de inscripción manual en el sitio:
Cuando el usuario se registra en el sitio.
Administración del sitio/Idioma/Personalización idioma
core: moodle.php
string: emailconfirmation
Escribir el texto HTML en la casilla «Traducción local personalizada» y guardar los cambios del paquete de idioma.

Personalizar email de solicitud de nueva contraseña:
Administración del sitio/Idioma/Personalización idioma
core: moodle.php
string: emailpasswordconfirmation
Escribir el texto HTML en la casilla «Traducción local personalizada» y guardar los cambios del paquete de idioma.

Personalizar email con nueva contraseña:
Administración del sitio/Idioma/Personalización idioma
core: moodle.php
string: newpasswordtext
Escribir el texto HTML en la casilla «Traducción local personalizada» y guardar los cambios del paquete de idioma.

Probado en Moodle 3.3.7, 3.8.5

miércoles, 1 de agosto de 2018

MySQL: Generar un número aleatorio



Para generar un número aleatorio entre un rango [mínimo, máximo], es decir inclusivo: n >= mínimo, n <= máximo.
FLOOR(RAND() * (máximo - mínimo + 1)) + mínimo;

Probado en MySQL 5.7

lunes, 16 de julio de 2018

miércoles, 31 de mayo de 2017

Abrir el mismo archivo en dos vistas. Sublime text






  • Ir al menú File
  • Luego a Split View

Versiones anteriores


1) En el menú File ir a New View into File. Esto permitirá tener el mismo archivo abierto en otra pestaña.

2) Ir al menú View y luego a Layout y después Columns: 2, por ejemplo, para tener dos paneles de trabajo (o el atajo de teclado alt + comand + 2)


3) Finalmente, arrastrar una de las pestañas al otro panel.

sábado, 11 de febrero de 2017

Tamaño de base de datos en MySQL



Con la siguiente consulta se puede obtener lo que ocupa una base de datos en MySQL


SELECT
table_schema as BasedeDatos,
sum( data_length + index_length ) / 1024 / 1024 as TamañoEnMB,
sum( data_free )/ 1024 / 1024 as EspacioLibreEnMB
FROM information_schema.TABLES
GROUP BY table_schema ;



Fuente: https://forums.mysql.com/read.php?108,201578,201578

miércoles, 7 de diciembre de 2016

Comentarios en el código

HTML

<!-- comentario de varias líneas -->

CSS

/* comentario de varias líneas */

SQL, PLSQL, PHP

# comentario de una línea
-- comentario de una línea
/* comentario de varias líneas */

C, C++, JAVA

// comentario de una línea
/* comentario de varias líneas */

Ensamblador

; comentario de una línea


miércoles, 30 de septiembre de 2015

Shell script para crear usuarios en linux (Debian)


A continuación se plantea un shell script que recibe como parámetro el nombre base para los usuarios a crear, el número de usuarios a generar y el grupo al que han de pertenecer. El número de usuarios es opcional siendo por defecto 5. El grupo al que han de pertenecer es opcional, siendo por defecto el nombre base que se da para generar los usuarios. No se realiza control de valides de argumentos, solamente el orden según se indica en el mensaje de uso.


#! /bin/bash

# Declaración de funciones
function mensaje_uso(){
    echo "ERROR: Número de parámetros incorrecto." >&2
    echo "USO: $0 <nombre_base> [-n <numero_de_usuarios>] [-g <nombre_de_grupo>]" >&2
    exit $salida  
}

function crea_grupo(){
    sentencia_crea_grupo="groupadd $nombre_grupo"
    $sentencia_crea_grupo 2> /dev/null #Supuesto de error es porque ya existe
}

function crea_usuario(){
    sentencia_crea_usuario="useradd -g $nombre_grupo $nombre_usuario"
    $sentencia_crea_usuario 2> /dev/null #Supuesto de error es porque ya existe
}

function asigna_grupo(){
    sentencia_cambio_grupo="adduser $nombre_usuario $nombre_grupo"
    $sentencia_cambio_grupo 1>&2> /dev/null #Nos aseguramos de que formen parte del grupo exigido
}

function asigna_passwd(){
    echo $nombre_usuario:$nombre_base | chpasswd    
}

# Inicialización de variables
ENE="-n"
GE="-g"
nombre_grupo=$1
nombre_base=$1
numero_usuarios=5
salida=1

# Control simple de argumentos
case "$#" in
    1)  case $1 in
            -h | --help | -help )
            salida=0 
            mensaje_uso 
            ;;
        esac
        #Se mantiene los valores por defecto
    ;;    
    3)
        if [ "$2" = "$ENE" ]; then
            numero_usuarios=$3
        else
            if [ "$2" = "$GE" ]; then
            nombre_grupo=$3
            else
                mensaje_uso
            fi
        fi
    ;;
    5)
        if [ "$2" = "$ENE" ]; then
            if [ "$4" = "$GE" ]; then
                numero_usuarios=$3
                nombre_grupo=$5
            else
                mensaje_uso
            fi
        else
            mensaje_uso
        fi
    ;;
    *) mensaje_uso
    ;;
esac

# Cuerpo
crea_grupo
 
for (( indice=1; indice <= $numero_usuarios; indice++ ))
    do
    nombre_usuario=$nombre_base$indice
    crea_usuario
    asigna_grupo
    asigna_passwd
done

exit 0


Se ha realizado en una máquina con Debian 7.0 (Wheezy) 

sábado, 19 de septiembre de 2015

Mostrar código con formato en una entrada del blog


Para escribir una entrada en el blog en la que se incluye código y se desea mostrar con un formato que lo diferencie, se puede utilizar la siguiente forma:

1) Escribir el código entre las etiquetas «pre» y «code». «code» indica que es código y «pre» nos facilita la interpretación de este, por ejemplo, evitando así la necesidad de incluir saltos de línea con formato html.
2) Aplicar estilos CSS.

Por ejemplo para mostrar el texto de la siguiente forma:

#!/bin/bash

echo ¡Hola mundo cruel!


El código utilizado es el siguiente:

<div id="codigo">
<pre><code>
#!/bin/bash

echo ¡Hola mundo cruel!

</code>
</pre>
</div>

<style>
#codigo{
color:#ffffff;
background:#000000;
}
</style>

Enlaces relacionados:
Mostrar HTML en una página web
Mostrar etiquetas html <>, sin que sean interpretadas por el navegador

martes, 1 de septiembre de 2015

Condición LIKE en Oracle SQL


Para condicionar en vez de utilizar un igual «=» en el que se comprueba carácter a carácter si son iguales:
('Francisco' = 'Francisco') es verdadero
('Fran     ' = 'Francisco') es falso

Con LIKE se puede condicionar utilizando comodines para realizar búsquedas como:

--Nombre de los empleados que su segunda letra, del nombre, sea una «a» minúscula.
SELECT first_name
FROM employees
WHERE first_name LIKE '_a%';

Comodines (wildcard)
Guión bajo «_» indica un carácter.
Porcentaje «%» indica cero o n caracteres.

--Nombre de los empleados que su nombre empiece por «S» y termine en «n».
SELECT first_name
FROM employees
WHERE first_name LIKE 'S%n';

Cuando tenemos la necesidad de indicar que buscamos en la cadena de caracteres uno de los caracteres comodines («_», «%»), especificamos un carácter de escape.

--Email de los empleados que contengan un guión bajo.
SELECT email
FROM employees
WHERE email LIKE '%@_%' ESCAPE '@';

En el ejemplo se ha utilizado como carácter de escape la arroba «@», podría ser otro carácter. Si coincide el carácter que especificamos fijo en la búsqueda y el de escape, simplemente se lo repite.

SELECT email
FROM employees
WHERE email LIKE '%__%' ESCAPE '_';

Si la comparación es de igualdad lo mejor es utilizar simplemente un igual «=»; en caso de solo una parte de la cadena, como por ejemplo que empiece por «A» lo mejor es utilizar la función SUBSTR y no un LIKE.

Más información: web Oracle

jueves, 29 de enero de 2015

JOINS con Oracle SQL


Voy a resumir rápidamente las diferentes formas de realizar una unión —JOIN, OUTER JOIN— de tablas en una sentencia SELECT. Aunque lo especificado en esta entrada se realiza utilizando Oracle, el lenguaje SQL es un estándar y por ello puede ser utilizado (suele haber pequeñas diferencias, por lo que hay que probar) en diferentes sistemas de gestión de bases de datos. Añado que, a lo largo de la entrada me refiero a «tabla» pero según el contexto puede ser en su lugar: vistas, subconsultas; y cuando me refiero a «campo» es el nombre de la columna; «fila» es una tupla; esto por familiarizar con diferentes formas de expresar para quienes se inician.

Utilizaré dos tipos de tablas para poner los ejemplos, es decir, unas inventadas por mí para ilustrar rápidamente y, las del esquema de ejemplo HR de Oracle que viene instalado o se puede crear desde Oracle, o buscando en internet los scripts.

Las tablas inventadas son las siguientes:


CROSS JOIN
Es el producto cartesiano, es decir, la relación de todas las filas de la tabla Emp con todas las filas de la tabla Dep y a su vez con todas las filas de la tabla Loc. Esto hay que conocerlo porque nos puede dar una pista de cuando nos salen más filas de las esperadas ya que no hemos especificado la condición de unión de las tablas según su relación.

En este pequeño ejemplo en el que en Emp hay 4 filas, Dep 3 filas y Loc 2 filas, obtenemos como resultado 24 filas = 4x3x2.

La sentencia escrita en dos formas:
SELECT emp.nombre, emp.depid, dep.depid, dep.nombre, loc.nombre
FROM emp, dep, loc; 
SELECT emp.nombre, emp.depid, dep.depid, dep.nombre, loc.nombre
FROM emp CROSS JOIN dep CROSS JOIN loc;
Si realizamos similar prueba con las tablas del esquema HR la sentencia sería:
SELECT first_name, department_name, city
FROM employees, departments, locations;
Dando como resultado 66447 filas = 107(Employees) x 27(Departments) x 23(Locations)

NATURAL JOIN
Lo que realiza es una unión por los campos de igual nombre, así que, hay que tener cuidado con esto pues hay quien lo utiliza para escribir menos y confía en que se realiza la unión por los campos clave. Pero, además puede estar realizando la unión por otros campos en los que coincide el nombre de las columnas. 

Empecemos con un ejemplo de las tablas de HR en el que deseamos el nombre de los empleados y el de su departamento.
SELECT first_name, department_name
FROM employees NATURAL JOIN departments;
Puede que pensemos que lo que se está haciendo es la unión por el campo con el que se relacionan las tablas, que es el número de departamento, la sentencia siguiente:
SELECT first_name, department_name
FROM employees, departments
WHERE employees.department_id = departments.department_id;
Pero, en realidad no lo es y nos da como resultado 32 filas, ya que en realidad la sentencia que está realizando sería:
SELECT first_name, department_name, department_id
FROM employees, departments
WHERE employees.department_id = departments.department_id
AND employees.manager_id = departments.manager_id;
En realidad ésta sentencia nos da los empleados que tienen el mismo jefe, tanto como jefe de empleado como jefe de departamento. Debido a que en las tablas Employees y Departments existen dos campos (nombre de columna) en los que coincide el nombre: manager_id y department_id. Si intentamos especificar en la Select uno de estos campos dará error si le anteponemos un nombre de tabla pues esta sentencia es específicamente para tratarlos como igual, así que no hay por qué diferenciar.

En el caso de las tablas que he inventado no obtendremos ninguna fila pues en las tres hay un campo que se llama: nombre. Y claro está que ningún valor coincide.

JOIN o simple join o inner join
Es la unión típica en la que se especifica el campo o campos que relacionan las tablas involucradas. Esto es, un campo primary key con uno foreign key. Los cuales surgen de una correcta modelización y paso al modelo relacional.

En el ejemplo se puede ver que salen únicamente las tuplas (filas) relacionadas. Es decir, Ana como no tiene un departamento no se muestra en el listado. Supongamos que aunque María sí esté en el departamento 20, el departamento 20 no tenga asignada una localidad, entonces tendremos como resultado solo dos filas en donde María no se listará.

Otra forma de escribir la misma sentencia es con la palabra JOIN y la cláusula USING:
SELECT emp.nombre, depid, dep.nombre, loc.nombre
FROM emp JOIN dep USING(depid)
                    JOIN loc USING(locid);
Es una forma en la que debemos tener en cuenta que: los nombres de los campos utilizados en la cláusula USING deben ser iguales en ambas tablas, y no puede anteponerse el nombre de ninguna tabla como podemos ver al utilizarlo en la parte de SELECT con el campo: depid, de igual modo si lo utilizamos en otra parte de la sentencia. Como podemos ver la especificación se hace escribiendo todo en el FROM; en el WHERE irán todas las condiciones restantes que no tienen que ver con la relación de las tablas. 

Lo que estamos diciendo es que Emp se une con Dep usando el campo depid y, a esa unión la unimos con la tabla Loc usando el campo locid. Repito: los nombres tienen que ser iguales pues de caso contrario no se puede realizar esta sintaxis. También, hay que tener en cuenta que si realizamos la unión por más de un campo se especifican separados por comas dentro del USING. Por ejemplo en el caso visto antes de los empleados que su jefe es el mismo que el jefe del departamento en el que trabajan se podría escribir de la siguiente forma.
SELECT first_name, department_name
FROM employees JOIN departments USING(department_id, manager_id);

Y obtendríamos las 32 filas mencionadas. Pero, debemos tomar en cuenta que aunque obtenemos los mismos resultados, por buenas prácticas debemos separar las condiciones de relación de las tablas (campos clave con campos ajenos) del resto de condiciones, en sentencias más grandes facilita el mantenimiento y la comprensión. Es decir, la sentencia sería:
SELECT first_name, department_name
FROM employees JOIN departments USING(department_id)
WHERE employees.manager_id = departments.manager_id;
Continuando con las tablas de HR la sentencia en la que se listan los empleados con su nombre, el nombre del departamento y la ciudad, tenemos:
SELECT first_name, department_name, city
FROM employees JOIN departments USING(department_id)
            JOIN locations USING(location_id);
El total de empleados es 107, pero se listan 106 pues hay uno que no tiene departamento. Y  hay que recordad que solo se listan las filas relacionadas.

Además, del JOIN y la cláusula USING, tenemos a JOIN con la cláusula ON en la que escribimos la condición de unión similar a como se haría en el WHERE. Ésta forma nos permite trabajar con campos en los que no coincidan el nombre en ambas tablas, porque igual se debe especificar y en caso de hacer referencia a uno de ellos sí hay que anteponer el nombre de la tabla; además, tiene la misma ventaja de separar las condiciones de unión del resto de condiciones del WHERE haciendo más legible la sentencia, por lo que es la opción que yo recomendaría. A continuación las sentencias que listan a los empleados de ambos ejemplos que utilizo.
SELECT emp.nombre, emp.depid, dep.nombre, loc.nombre
FROM emp JOIN dep ON(emp.depid = dep.depid)
                    JOIN loc ON(dep.locid = loc.locid);
SELECT first_name, department_name, city
FROM employees JOIN departments ON(employees.department_id = departments.department_id)
            JOIN locations ON(departments.location_id = locations.location_id);
OUTER JOIN
Son útiles para mostrar filas que no están relacionadas, además de las relacionadas. En el ejemplo sencillo en el que Ana no se muestra, supongamos que queremos listar todos los empleados independientemente de si están o no relacionados. 
Con LEFT JOIN (LEFT OUTER JOIN) lo que indicamos es que la tabla a la izquierda es de la que quiero todas las filas independientemente de que sus filas se relacionen. El segundo LEFT JOIN es necesario pues a la primera unión vamos a relacionarla con la tercera tabla (Loc) y si es a la izquierda donde se encuentra la información que queremos listar se relacione o no. Así que, el que sea LEFT JOIN es porque tal y como se ha escrito está a la izquierda, pues si lo ponemos en otro orden y queremos los mismos resultados hay que tener en cuenta hacia qué lado está lo que queremos listar aunque no esté relacionado. Supongamos que queremos lo mismo pero escribimos las tablas en el orden inverso. Entonces en éste caso la tabla de empleados estará a la derecha por lo que la sentencia sería con RIGHT JOIN (RIGHT OUTER JOIN):
Ahora queremos todos los departamentos, que tal como podemos comprobar con los datos existe el 30 que no se relaciona. Y vamos a escribir la sentencia dejando a la tabla dep en el centro simplemente para ilustrar que hay que escribir los JOIN en función del orden en el que escribimos.
Como se puede ver se lista el departamento 30 que no tiene localidad y Ana no se muestra. Antes de que exista el estándar de 1999, que es el que utiliza la palabra JOIN, utilizando la forma antigua con WHERE se escribiría de la siguiente forma:
En éste caso se coloca un signo más entre paréntesis al campo de la tabla que queremos rellene o no tome en cuenta. Como queríamos todas las filas de Dep colocamos el símbolo a Emp y Loc. Para el caso de las tablas de HR, manteniendo el supuesto de que queremos todos los departamentos además de los datos relacionados, que son 106 filas, la sentencia en la que obtendríamos 122 filas sería:
SELECT first_name, department_name, cityFROM employees RIGHT JOIN departments ON(employees.department_id = departments.department_id)LEFT JOIN locations ON(departments.location_id = locations.location_id); 
SELECT first_name, department_nameFROM employees, departments, locationsWHERE employees.department_id(+) = departments.department_id       AND departments.location_id = locations.location_id(+);
Por último, ahora suponemos que queremos listar todos los empleados, departamentos y localidades estén o no relacionados. Entonces se nos puede ocurrir poner el símbolo (+) a ambos lados del igual. Pero, esto no se permite. Con esta sintaxis anterior al estándar del 99, se tenía que idear otra forma. Así que, sumamos otra ventaja al estándar del 99 que lo permite con FULL JOIN (FULL OUTER JOIN).
SELECT first_name, department_name, cityFROM employees FULL JOIN departments ON(employees.department_id = departments.department_id)FULL JOIN locations ON(departments.location_id = locations.location_id); 
En el caso de las tablas de HR obtenemos 139 filas. Y en nuestro pequeño ejemplo:
Como se ve en la imagen están las 3 filas que se relacionan, la empleada que no tiene departamento, el departamento que no tiene localidad y la localidad que no se relaciona, teniendo así las 6 filas que se listan. A partir de aquí, podemos mezclar por ejemplo al suponer que queremos todos los empleados y departamentos pero las ciudades nos basta con las que se relacionan, entonces tendríamos:
SELECT emp.nombre, emp.depid, dep.nombre, loc.nombre
FROM emp FULL JOIN dep ON(emp.depid = dep.depid)
                    LEFT JOIN loc ON(dep.locid = loc.locid);


Realizado con:—Oracle Database 10g
—Aplicación desde terminal SQLPLUS

miércoles, 24 de diciembre de 2014

Vaciar cadena en C


Para limpiar o vaciar la basura que pueda contener una cadena de tipo char en lenguaje C he utilizado la función memset. Debido a que intentaba concatenar continuamente valores y en determinado momento poner valores de tamaño menor; sin embargo, el resultado era que sobrescribía los caracteres pero quedaban los existentes anteriormente. Es decir, si antes estaba la cadena «cadena» y luego escribía un «uno», el resultado esperado era tener «uno», pero se obtiene «unoena». Lo solucioné al utilizar la función memset que sobrescribe los valores en memoria con el valor del segundo parámetro.

char varCadena[50];
...
memset(varCadena, 0, 50); //limpiar para que no lo una con la basura

Donde:
varCadena: es la variable de tipo char
0: el valor con el cual rellenar
50: la longitud de la cadena

miércoles, 4 de julio de 2012

Eliminar sin pasar por la papelera en Mac

Cuando nos pasamos de Windows a Mac uno de los primeros golpes sufridos es cuando estamos acostumbrados a eliminar archivos definitivamente sin enviarlos a la papelera presionando Shift + Supr. En Mac nos encontramos como si nos faltara esa funcionalidad ya que solo vemos la opción de eliminarlos y que vayan a la papelera. En Mac para liberar ese espacio y eliminar definitivamente los ficheros la opción visible que nos dan es el vaciar la papelera.

Shift + supr en MAC

Desde OS X El Capitan se puede realizar presionando option + Command + borrar.

En versiones anteriores 

Tendremos que hacerlo con mandatos desde terminal o programarlo mediante automator.

Abrimos automator, que lo tendremos entre nuestras aplicaciones.
Logo Automator

Elegimos la plantilla para flujo de trabajo de Servicio.
Seleccionada plantilla de trabajo: Servicio
Tenemos tres columnas, en la de la derecha, en el menú desplegable que dice: «El servicio recibe la selección de» archivos o carpetas «en» Finder.

En la columna central buscamos y damos doble clic, o arrastramos a la zona centrar de la columna derecha: Obtener los ítems del Finder seleccionados; y Ejecutar el script Shell.

En la sección de «Ejecutar el script shell» se escoge del menú desplegable donde dice «pasar datos de entrada» como argumentos.

Modificamos el código dejándolo de la siguiente forma:


for f in "$@"
do
rm -R -f -d "$f"
done


Finalmente se guarda: Archivo—guardar. y le damos un nombre, por ejemplo: ShiftSupr
Ventana de trabajo de Automator

Luego abrimos Preferencias del sistema.

En la sección Hardware, clic en Teclado.

Seleccionado la opción de «Funciones rápidas de teclado» en la cabecera. Tendremos dos cajas, en la de la izquierda seleccionamos «Servicios» y en la derecha nos dirigimos a la sección de «Archivos y carpetas» donde tendremos el nombre del archivo que acabamos de guardar ShiftSupr. Damos un clic en la parte derecha para poder asignar el atajo de teclado y una vez que se activa la edición presionamos las teclas, como por ejemplo: shift+cmd+S. Intentar, por seguridad, que sea una combinación que no se presione fácilmente por error.

De este modo al seleccionar archivos o carpetas y presionar la combinación de teclas se eliminarán sin ir a la papelera, liberando de espacio al disco automáticamente.

Para más información sobre el mandato rm. Podéis abrir el terminal y escribir: man rm y os mostrará la descripción con las opciones y su significado.

El script eliminará archivos y carpetas sin pedir confirmación, si están bloqueados no los eliminará porque no eres un administrador. Si eliminas algo que no querías tendrás que buscar programas de recuperación de datos.

Los archivos .workflow creados con Automator se guardan en: «~/Library/Services»

Realizado y probado en:
—Mac OS X 10.6.8 Snow Leopard
—Mac OS X 10.9.1 Mavericks
—Mac OS X 10.10.1 Yosemite
—Mac OS X 10.11.3 El Capitan

jueves, 29 de marzo de 2012

ORDER BY. Oracle.

Diagrama de ORDER BY

Para ordenar las filas devueltas por una select utilizamos la cláusula ORDER BY, la cual va al final de toda la SELECT.
SELECT       ename, sal,comm,sal+comm total
FROM           emp
ORDER BY  ename;
Significaría que muestre ordenado por el campo «ename» en orden ascendente.

Salida de select de ejemplo

Se puede ordenar por más de un campo, e indicar individualmente si ascendentemente (ASC) o descendentemente (DESC). Por defecto el orden es ascendente.
SELECT      ename, sal,comm,sal+comm total
FROM          emp
ORDER BY sal ASC, total DESC, 1 ASC;
Salida de select de ejemplo
Se ordena primero por el campo «sal» en orden ascendente y en caso de similares «1250» se ordena por el siguiente campo especificado «total —alias de sal+comm—» en orden descendente . Y en caso de iguales, se ordenará por la tercera opción que es «1 —corresponde al campo "ename" que es el primero» en orden ascendente (ej: cuando sal es 3000 y total null).
Se puede utilizar para hacer referencia a la columna por la cual se quiere ordenar: el nombre, el alias o el orden que ocupa en la select. No se puede utilizar expresiones (ej: sal+com, to_char(fecha,'mm')).

Los campos de la cláusula ORDER BY tienen que ser campos pertenecientes a los objetos especificados en el FROM (tablas, vistas, subconsultas), es decir, se puede ordenar por un campo que no necesariamente tiene por qué ser seleccionado. Por ejemplo, podríamos ordenar por «ename» y la SELECT ser: «sal,comm+sal» (excluyendo a «ename»).

Además de ordenar por los campos que tienen datos, se puede especificar si  queremos los nulos al inicio (FIRST) o al final (LAST) de todo. Por defecto cuando es descendente los nulos van al inicio, y cuando es ascendente los nulos van al final.
SELECT      ename, sal,comm,sal+comm total
FROM          emp
ORDER BY total DESC NULLS LAST;
Salida de select de ejemplo

En caso de utilizar los operadores de conjunto: INTERSECT, MINUS, UNION, UNION ALL, se escribe una sola  cláusula ORDER BY que se coloca al final del todo y solo una.
SELECT ename
FROM    emp
MINUS
SELECT UPPER(first_name)
FROM   employees
ORDER BY ename;
A la primer select se le restan los elementos que coinciden con la segunda select («JAMES») y al resultado de todo se lo ordena. Se utiliza la función UPPER para transformar los datos que provienen de la tabla «employees» a mayúsculas.
En caso de querer filtrar por el número de fila ROWNUM de una ordenación. Hay que saber lo que se hace. Por ejemplo queremos a los tres que ganan más.

ROWNUM nos indica el número de la fila y no cambiará aunque cambiemos el orden.

Así que si pensamos en obtener los tres que ganan más. Y pensamos en la siguiente SELECT:

Si comparamos con la SELECT  en la que vemos a todos, notamos que no es lo que queremos.

Una alternativa es primero ordenarlos en una subconsulta y a esas filas filtrarlas por el ROWNUM.

Si se quiere optimizar, es recomendable evitar ordenar los datos para evitar el darle ese trabajo extra a la base de datos. Hacerlo únicamente cuando estemos obligados a eso. Analizarlo.
Por ejemplo, con tan solo catorce filas se puede ver cómo el coste aumenta, de realizar una SELECT («ename,sal») sin ordenar, y la misma ordenando (por «sal»). No pensar en que si se ordena por un campo indexado va a ir más rápido.


Se ha utilizado:
—Windows XP SP3
—Oracle Data Base 11.2.0.1
—SQL*PLUS 11.2.0.1
—Tablas de los esquemas SCOTT (emp) y HR(employees)