jueves, 20 de junio de 2019

Camunda Sql Server descodificar campo BYTEARRAY

 Si hemos almacenado información en una variable de proceso, por ejemplo un JSON y como repositorio utilizamos Sql Server.

Para poder recuperar la información de una para visualizarla o realizar búsquedas directamente en la base de datos sin pasar por el API REST.

Podemos usar una sentencia de esta forma:

select * from
(
select CAST(  CAST(bytes_ AS varbinary(MAX)) as varchar(max)) as campo
from [dbo].[ACT_GE_BYTEARRAY] where id_ in ( select bytearray_id_ from dbo.ACT_RU_VARIABLE where name_ like '' )
) as pepe
where campo like '{"id":13%'

lunes, 15 de abril de 2019

Switch, factoría, tester/doer

Ejemplo de como quitar un switch y sustituirlo por una factoria:

public void ProcessCustomer(CustomerMessage message)
{
  switch (message.CustomerCategory)
  {
    case Category.Gold:
      ProcessGoldCustomer(message);
      break;
    case Category.Silver:
      ProcessSilverCustomer(message);
      break;
    case Category.Bronze:
      ProcessBronzeCustomer(message);
      break;
  }
}
 
Ejemplo con factoría:
 
public interface ICustomerProcessor
{
  void Process(CustomerMessage message);
}
 
public class GoldCustomerProcessor : ICustomerProcessor {...}
public class SilverCustomerProcessor : ICustomerProcessor {...}
public class BronzeCustomerProcessor : ICustomerProcessor {...}
 
public class CustomerProcessorFactory
{
  public ICustomerProcessor Create(Category category) {
    switch (category) {   
      case Category.Gold: 
        return new GoldCustomerProcessor();
    }
    ...
  }
}
 
public void ProcessCustomer(CustomerMessage message)
{
  var factory = new CustomerProcessorFactory();
  var processor = factory.Create(message.CustomerCategory);
  processor.Process(message);
}
 
Ejemplo patrón Tester/Doer:
 
public interface ICustomerProcessor
{
  bool CanProcess(CustomerMessage message);
  void Process(CustomerMessage message);
}
 
public class GoldCustomerProcessor : ICustomerProcessor
{
  public bool CanProcess(CustomerMessage message)
  {
    return message.CustomerCategory == Category.Gold;
  }
   
  public void Process(CustomerMessage message) {...}
}
 
public class SilverCustomerProcessor : ICustomerProcessor {...}
public class BronzeCustomerProcessor : ICustomerProcessor {...}
 
public void ProcessCustomer(CustomerMessage message)
{
  var processor = this.processors.Single(x => x.CanProcess(message));
  processor.Process(message);
}
 

martes, 26 de junio de 2018

Lambdas y Closures diferencias

Este hilo de StackOverflow explica con mucho detalle de donde proceden las funciones lambda y sus diferencias con Closures. Lo hace de forma agnostica a cualquier lenguaje.


No es la respuesta con más puntos positivos, sino la respuesta que habla sobre Lambda Calculus invented by Alonzo Church.

what-is-the-difference-between-a-closure-and-a-lambda

martes, 29 de mayo de 2018

SQL vs Java 8 Stream

Para entender los streams de Java 8 lo mejor es compararlos con sus equivalentes de SQL.

SQL Equivalente interfaz stream
from stream()
select map()
where filter() (antes de un collecting)
order by sorted()
distinct distinct()
having filter() (después de un collecting)
join flatMap()
union concat().distinct()
offset skip()
limit limit()
group by collect(groupingBy())
count count()

En el siguiente enlace podrás encontrar más ejemplos.

Fuente: https://windoctor7.github.io/API-Stream-Java8.html

lunes, 28 de mayo de 2018

Indices en Postgresql

Hay una serie de índices aparte de los convencionales, que son poco conocidos, pero no por ello dejan de ser muy útiles.

GIN - índices optimizados para la búsqueda de subelementos, dentro de una columna, por ejemplo columnas de tipo Array, columnas que almacenen JSON o campos de texto para hacer búsquedas FTS (Full Text Search).

GIST - índices para búsquedas de datos geolocalizados.

BRIN - índices que ahorra espacio de almacenamiento para aquellos datos que se encuentran ordenados de forma natural. Por ejemplo las entradas de un fichero log, siempre se generan de forma secuencial en base al campo de fecha de la entrada.

HASH - indice optimizado en velocidad para la búsqueda de elementos por igualdad. Por ejemplo la dirección de email de usuarios. Usando este índice tendríamos máxima velocidad de acceso para buscar a un usuario por su email.

jueves, 2 de febrero de 2017

Angular UI Bootstrap. Datepicker de un rango de fechas.

Para definir en nuestros formularios de angular unos datepicker muy útiles.

Primero definimos los campos en la página html.

Vamos a crear dos datepicker que definan un rango, no permitiendo que el rango final sea superior al inicial. Además el inicial solo podrá elegirse el primer día de un mes y para el final solo el último día de un mes.

Creamos una fecha para un rango inicial:

<div class="col-input">
    <div class="form-group">
        <label for="fechaInicio">Fecha de Inicio</label>
        <div class="input-group">
            <input id="fechaInicio" name="fechaInicio"
                   type="text" class="form-control"
                   uib-datepicker-popup="{{$ctrl.viewModel.format}}"
                   ng-model="$ctrl.viewModel.Dto.fechaInicio"
                   ng-model-options="{timezone: 'utc'}"
                   ng-change="$ctrl.viewModel.changeFechaInicio()"
                   is-open="$ctrl.viewModel.popup1.opened"
                   datepicker-options="$ctrl.viewModel.dateOptionsFechaInicio"
                   ng-required="true"
                   close-text="Cerrar"
                   current-text="Hoy"
                   clear-text="Limpiar"
                   alt-input-formats="$ctrl.viewModel.altInputFormats"
                   ng-disabled="$ctrl.viewModel.flags.disabledFechaInicio" />
            <span class="input-group-btn">
                <button type="button" class="btn btn-default pull-left"
                        ng-click="$ctrl.viewModel.open1($event)">
                    <i class="glyphicon glyphicon-calendar"></i>
                </button>
            </span>
        </div>
    </div>
</div>

Y otra fecha para el final del rango:

<div class="col-input">
    <div class="form-group">
        <label for="fechaFin">Fecha de Fin</label>
        <div class="input-group">
            <input id="fechaFin" name="fechaFin"
                   type="text" class="form-control"
                   uib-datepicker-popup="{{$ctrl.viewModel.format}}"
                   ng-model="$ctrl.viewModel.Dto.fechaFin"
                   ng-model-options="{timezone: 'utc'}"
                   ng-change="$ctrl.viewModel.changeFechaFin()"
                   is-open="$ctrl.viewModel.popup2.opened"
                   datepicker-options="$ctrl.viewModel.dateOptionsFechaFin"
                   ng-required="true"
                   close-text="Cerrar"
                   current-text="Hoy"
                   clear-text="Limpiar"
                   alt-input-formats="$ctrl.viewModel.altInputFormats"
                   ng-disabled="$ctrl.viewModel.flags.disabledFechaFin" />
            <span class="input-group-btn">
                <button type="button" class="btn btn-default"
                        ng-click="$ctrl.viewModel.open2($event)">
                    <i class="glyphicon glyphicon-calendar"></i>
                </button>
            </span>
        </div>
    </div>
</div>

Ahora vamos a definir en nuestro ViewModel de Angular las opciones de cada campo:


this.generalDateOptions = {
    formatYear: 'yy',
    startingDay: 1,
    showWeeks: false,
    prevText: ',
    nextText: 'Sig>',
    currentText: 'Hoy'
};
 
this.dateOptionsFechaInicio          = JSON.parse(JSON.stringify(this.generalDateOptions));
this.dateOptionsFechaInicio.minMode = 'month';
this.dateOptionsFechaInicio.minDate = new Date();
 
this.dateOptionsFechaFin             = JSON.parse(JSON.stringify(this.generalDateOptions));

La variable generalDateOptions, es la configuración común a todos los campos fecha que tengamos en nuestros formularios.

Luego personalizamos algunos de los parámetros de la configuración, como por ejemplo indicamos que para la fecha de inicio, queremos selección por meses no por días (minMode='month') y que queremos que la fecha mínima seleccionamble sea la fecha actual.

A continuación vamos a preparar las funciones de callback (open1 y open2), que serán llamadas cuando se pulse en el icono para abrir el control Datepicker. Aqui vamos a hacer depender la fecha final del rango de la fecha inicial que se haya elegido, no permitiendo elegir un dia menor.
Además vamos a desactivar todos los días del mes, menos el último (disableNotLastDayOfMonth)

this.popup1 = {
    opened: false
};
this.popup2 = {
    opened: false
};

this.open1 = function ($event) {
 
      this.popup1.opened = true;
};
this.open2 = function ($event) {
      this.dateOptionsFechaFin.minDate  = this.Dto.fechaInicio;
      this.dateOptionsFechaFin.initDate = this.dateOptionsFechaFin.minDate;
      // Desactivamos todos los días del mes menos el último
      this.dateOptionsFechaFin.dateDisabled = this.disableNotLastDayOfMonth;
      this.dateOptionsFechaFin.minMode = 'month';
      this.popup2.opened = true;
};

// Función que habilita solo las fechas que son fin de mes
this.disableNotLastDayOfMonth = function (obj) {
    var date = obj.date, mode = obj.mode;
    if (date.getDate() > 27) {
        var comprobar = new Date();
        comprobar.setFullYear(date.getFullYear(), date.getMonth() + 1, 0);
 
        if (comprobar.getDay() === date.getDay()) {
            return false;
        }
    }
    return mode === 'day' && true;
};



Podeis encontrar toda las opciones y documentación en:
https://angular-ui.github.io/bootstrap/

jueves, 2 de junio de 2016

Gestión de transacciones declarativas en Spring.

Es muy interesante poder definir de forma declarativa en el código, el ámbito de nuestras transacciones. 
Hay 7 tipos de propagación de las transacciones en Spring:

  • PROPAGATION_REQUIRED - Crea una nueva transacción si no existe. Si existe participa en ella. PROPAGATION_SUPPORTS - No crea una nueva transacción si no existe. Si existe participa en ella. 
  • PROPAGATION_MANDATORY - Si existe transacción participa en ella. Si no existe lanza una excepción. 
  • PROPAGATION_REQUIRES_NEW - Crea una nueva transacción. Si existe una transacción actual la suspende. 
  • PROPAGATION_NOT_SUPPORTED - No participa en la transacción actual y se ejecuta de forma no transaccional. 
  • PROPAGATION_NEVER - Si existe una transacción actualmente lanza una excepción. PROPAGATION_NESTED - Ejecuta una transacción anidada si existe una transacción actualmente. El caso más habitual es 
  • PROPAGATION_REQUIRED. http://www.mkyong.com/spring/spring-aop-transaction-management-in-hibernate/

martes, 31 de mayo de 2016

Conversión de fechas de cadena Java

Como formatear una fecha en una cadena tipo: "martes, 31 de mayo de 2016" A una fecha Java. java.text.SimpleDateFormat formatter=new SimpleDateFormat("EEEE, dd 'de' MMMM 'de' yyyy"); java.util.Date date=null; try { date = formatter.parse(peticionDia.getDia()); } catch (ParseException e) { e.printStackTrace(); }

lunes, 28 de septiembre de 2015

Hibernate join con condición adicional

Puede que tengamos escrito en HQL, sentencias que realizan joins de nuestras entidades. La ventaja de Hibernate es que como conoce las dependencias, no tenemos que indicar la condición del join entre cada una de nuestras tablas. Por ejemplo from Cat as cat join cat.mate as mate left join cat.kittens as kitten Pero que ocurre si no queremos que el join nos traiga el contenido de la tabla relacionada, bajo alguna circunstancia que se encuentra en dicha tabla relacionada. La solución es usar la clausula "with" que se asemeja a un and, y donde podemos especificar la condición que debe cumplirse para que el join sea efectivo y devuelva la fila de la entidad relacionada. from Cat as cat left join cat.kittens as kitten with kitten.bodyWeight > 10.0

jueves, 30 de julio de 2015

Instalación y administración Tomcat 7 en Windows

Instalación


Si quieres instalar Tomcat como ejecutable, no como servicio, en tu máquina windows.

Baja el fichero .zip correspondiente de 32 o 64 bits. Desde https://tomcat.apache.org/download-70.cgi

Descomprimelo en una carpeta. Por ejemplo: c:\tomcat7

Abre una consola de windows.

Establece las variables de entorno donde tengas instalado el jdk

set PATH=%PATH%;C:\Program Files\Java\jdk1.7.0_71\bin
set JAVA_HOME=C:\Archivos de programa\Java\jdk1.7.0_71

Dirigete a c:\tomcat7\bin y ejecuta startup.bat

Y ahora abre un navegador con la dirección: http:\\localhost:8080

Voila!

Si quieres parar Tomcat, en la misma consola de windows donde ejecutaste startup.bat, solo tienes que ejecutar shutdown.bat

Consola de administración

Edita el fichero c:\tomcat7\conf\tomcat-users.xml para que tenga la forma:


Accede a la siguiente dirección y cuando pida contraseña utiliza la definida en el anterior fichero:

http://localhost:8080/manager


Ampliación de memoria

Si tienes problemas de memoria al arrancar las aplicaciones, tienes que crear un fichero con nombre setenv.bat en el directorio c:\tomcat7\conf

set "CATALINA_OPTS=%CATALINA_OPTS% -Dfile.encoding=UTF8 -Xmx2048m -XX:MaxPermSize=512m"

Cambio de Puerto

Editar el fichero c:\tomcat\conf\server.xml cambiar el puerto 8080 por ejemplo por el 7001:


               < Connector port="7001" protocol="HTTP/1.1" connectionTimeout="20000"
               redirectPort="8443" />

Si además queremos tener dos tomcat arrancados en la misma máquina habremos de cambiar el puerto 8005 y el puerto 8009:

               < Server port="8015" shutdown="SHUTDOWN" />

               ....
               < Connector port="8019" protocol="AJP/1.3" redirectPort="8443" />




martes, 21 de abril de 2015

Java. Guardar una cadena en un fichero

En un proyecto Java, componía un xml a traves de una serie de consultas las cuales necesitaban un tiempo de proceso muy largo.

Para mejorar el rendimiento y devolver el xml si no había habido cambios en las tablas relacionadas, puede servir una caché primitiva como esta. Un método guarda el string del xml en un fichero y otro método lo lee y lo devuelve.


private void GuardarXmlCache ( String nombreFichero, String xml) {
try(FileOutputStream fos=new FileOutputStream(nombreFichero)){
fos.write(xml.getBytes());
fos.close();
}catch(IOException e){

}

}


private String LeerXmlCache ( String nombreFichero) {
FileInputStream fos = null;
String message  = new String();
try {
fos=new FileInputStream(nombreFichero);
BufferedReader rd = new BufferedReader (new InputStreamReader(fos,"UTF-8"));
String line=null;
//final StringBuffer buffer = new StringBuffer(2048);
while ((line = rd.readLine()) != null) {

message += line;
}        
rd.close();
 
}catch(IOException e){
e.printStackTrace();
}
return message;
}

jueves, 19 de febrero de 2015

analizando consultas en Postgresql. Parte I

Tenemos una potente herramienta para analizar las consultas en PostgreSQL: explain analyze

explain analyze select * from usuario;

Seq Scan on usuario  (cost=0.00..4743.71 rows=44471 width=243) (actual time=0.026..59.431 rows=44474 loops=1)

 Total runtime: 63.645 ms

(2 filas)

Seq Scan, significa que la consulta se hará fila a fila secuencialmente sin acceso por índice.

El valor numérico cost=0,00, es el tiempo que tiene que esperar la consulta en ser ejecutada. En este caso el tiempo es 0.00 porque puede ejecutarse inmediatamente.

El segundo valor 4743,71, es el numero de fetches necesarios para recuperar todas las filas de la consulta, el número de fetches lo podemos minimizar por ejemplo aplicando LIMIT.

Rows=44.471 es el número de filas que devolverá la consulta y width el tamaño medio en bytes de cada fila.

Truco: si vas a realizar análisis de operaciones de escritura, encierralas en un bloque de transacción, para poder ejecutarlas las veces que necesites y que no se produzcan cambios en la base de datos:

begin;
explain analyze insert ...;
rollback;

lunes, 15 de diciembre de 2014

Usuario de solo lectura

A veces puedes necesitar dar acceso a tu base de datos a una herramienta de terceros, de la cual no te fias o solo quieres que haga consultas pero no toque nada. Una forma rápida es crear un usuario de solo lectura:

create user 'readonly' password 'laquesea';
alter user readonly set default_transaction_read_only = on;

Luego puedes darle permiso sobre todas las tablas de los esquemas que necesites:






select 'grant select on ' || a.schemaname || '.' || a.tablename || ' to readonly;' from pg_tables a where schemaname in ('esquema1');
select 'grant select on ' || a.schemaname || '.' || a.tablename || ' to readonly;' from pg_tables a where schemaname in ('esquema2');

Y por último dale permisos de acceso a los esquemas:

grant usage on schema cromos to readonly;
grant usage on schema coleccion to readonly;

lunes, 6 de octubre de 2014

Bloque anónimo

A veces necesitas hacer uso de las estructuras de plpgsql, por ejemplo, en scripts .sql que llamas desde tareas del cron, etc. Para ello tenemos los bloques DO.

A continuación un bloque sencillo, que comprueba si es primeros de mes y añade un mes de antigüedad a los usuarios registrados. Como puedes ver podemos utilizar variables y ejecutar comandos de los cuales no necesito conocer el resultado (perform).

do $$
declare
  dia integer;
begin
  select extract ('day' from current_date) into dia from editorial;
  if dia = 1 then
    perform 'update usuario set months=months+1';
  else
    raise notice 'Hoy no es día 1';
  end if;
end$$;

martes, 12 de agosto de 2014

Cambiar atributos default o not null a una columna existente

Si quieres quitar la propiedad default o not null a una columna existente;

alter table  alter column  drop not null;

alter table  alter column  drop default;


Por el contrario, si quieres añadir el atributo not null o la propiedad default:

alter table  alter column  set not null;

alter table  alter column  set default current_timestamp;



Ultimo id insertado

Cuando queremos recuperar el último id insertado en una tabla, para por ejemplo asignarlo en los registros de sus hijas. Lo habitual es consultar el último valor de la secuencia asociada al campo clave. Por ejemplo:
 
select currval('cambio_id_seq');
 
En este caso tenemos que conocer el nombre de la secuencia, si lo desconociésemos podríamos utilizar la función pg_get_serial_sequence que nos proporcionaría el nombre de la secuencia asociado a un campo determinado de una tabla:

select currval(pg_get_serial_squence('cambio','id'));

Esta opción tiene un problema. Solo nos funcionará si nadie más utiliza dicha secuencia en otra sesión. Es decir en entorno de multiples conexiones no es recomendable.

Por el contrario LASTVAL(), está aislado a nivel de sesión, por lo que no tiene dichos efectos indeseados

Pero si la tabla tuviese un trigger que insertará nuevos registros o modificara la secuencia por algún motivo, LASTVAL() no funcionaría correctamente. 

Por todo lo anterior, el mejor método posible es utilizar la clausula RETURNING después de la inserción. Por ejemplo:

    insert into cambio (id,usuario1,usuario2)
    values (DEFAULT,usuario1_id,usuario2_id)
    RETURNING id into cambio_id;


En la variable cambio_id tendremos almacenado seguro el valor de la inserción que estamos haciendo en nuestra sesión, sin efecto colateral alguno.

miércoles, 16 de julio de 2014

OpenXava combos

Construyendo administradores backend para una web. Busqué información para la construcción de los típicos combos que facilitan la selección de un valor de una tabla maestra para copiarlo en el campo de una tabla o mostrar su descripción.


Por ejemplo, teniendo una tabla card con varios campos de referencia a otra tabla skill. Y teniendo campos card1,card2 que hacen referencia a la propia tabla la clase quedaría así:



import java.io.Serializable;
import java.util.Collection;
import javax.persistence.*;
import org.openxava.annotations.*;
@Entity
@Table(name = "card", catalog = "soccer", schema = "master")
@View(members=
"Otros datos [#id,name;description;];"+
 " [rarity, type, subtype;" +
"price, points, cost, dust;" +
"health, ability, level, collectible;" +
"image, frame, cardset;" +
"skill1; skill2; skill3;" +
"card1Id; card2Id;" +
"classId;" +
"];" +
"cardPackCollection")
public class Card implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    @DisplaySize(10)
    private Integer id;
    @Basic(optional = false)
    @Column(name = "name")
    @DisplaySize(40)
    private String name;
    @Basic(optional = false)
    @Column(name = "description")
    @DisplaySize(120)
    private String description;
   
    @ManyToOne(fetch=FetchType.LAZY)   
    @JoinColumn(name="skill1")
    @DescriptionsList(
      descriptionProperties="id,name",
      order="name"
    )
    private Skill skill1;
   
    @ManyToOne(fetch=FetchType.LAZY)   
    @JoinColumn(name="skill2")
    @DescriptionsList(
      descriptionProperties="id,name",
      order="name"
    )   
    private Skill skill2;
   
    @ManyToOne(fetch=FetchType.LAZY)   
    @JoinColumn(name="skill3")
    @DescriptionsList(
      descriptionProperties="id,name",
      order="name"
    )
    private Skill skill3;
    @ManyToOne(fetch=FetchType.LAZY)   
    @JoinColumn(name="card1_id")
    @DescriptionsList(
      descriptionProperties="id,name",
      order="name"
    )   
    private Card card1Id;
   
   
    @ManyToOne(fetch=FetchType.LAZY)   
    @JoinColumn(name="card2_id")
    @DescriptionsList(
      descriptionProperties="id,name",
      order="name"
    )         
    private Integer card2Id;
      
    @OneToMany(mappedBy = "cardId", fetch = FetchType.LAZY)
    private Collection cardPackCollection;
    public Card() {
    }
    public Card(Integer id) {
        this.id = id;
    }
    public Card(Integer id, String name, String description, Card card1Id, int card2Id ) {
        this.id   = id;
        this.name   = name;
        this.description= description;
        this.card1Id = card1Id;
        this.card2Id = card2Id;
    }
    public Integer getId() {
  return id;
 }
 public void setId(Integer id) {
  this.id = id;
 }
 public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public Skill getSkill1() {
        return skill1;
    }
    public void setSkill1(Skill skill1) {
        this.skill1 = skill1;
    }
    public Skill getSkill2() {
        return skill2;
    }
    public void setSkill2(Skill skill2) {
        this.skill2 = skill2;
    }
    public Skill getSkill3() {
        return skill3;
    }
    public void setSkill3(Skill skill3) {
        this.skill3 = skill3;
    }
   
    public Card getCard1Id() {
 return card1Id;
    }
    public void setCard1Id(Card card1Id) {
 this.card1Id = card1Id;
    }
    public Integer getCard2Id() {
 return card2Id;
    }
    public void setCard2Id(Integer card2Id) {
 this.card2Id = card2Id;
    }

    public Collection getCardPackCollection() {
        return cardPackCollection;
    }
    public void setCardPackCollection(Collection cardPackCollection) {
        this.cardPackCollection = cardPackCollection;
    }
}




martes, 27 de mayo de 2014

Script migración tablas sueltas

Script de apoyo para mover el contenido una serie de tablas de una base de datos a otra.
Toma el contenido de las tablas tabla1..tabla4 y lo vuelca en /tmp/fichero.dump sin tomar la estructura de la tabla.
Utiliza unas tablas auxiliares para guardar el contenido de las tablas que tienen relaciones con tabla1..tabla4.
Vacía las tablas tabla2_related1..tabla2_related3 con relaciones sobre las tablas que estamos moviendo.
Posteriormente vacía las tablas destino tabla1..tabla4 y despues las rellena con el contenido del fichero /tmp/fichero.dump
Por último restaura el contenido de las tablas con relaciones, utilizando la cópia almacenada en las tablas auxiliares.
Espero que os pueda servir de ayuda en alguna ocasión.


#Volcado de las tablas originales deseadas (primero las maestras luego las dependientes)
pg_dump -U -h -p --inserts --data-only -t tabla1  >  /tmp/fichero.dump
pg_dump -U -h -p --inserts --data-only -t tabla2 >> /tmp/fichero.dump
pg_dump -U -h -p --inserts --data-only -t tabla3 >> /tmp/fichero.dump
pg_dump -U -h -p --inserts --data-only -t tabla4 >> /tmp/fichero.dump

#Borrado de las auxiliares
psql -h -U -p -c "drop table schema.aux_tabla2_related1"
psql -h -U -p -c "drop table schema.aux_tabla2_related2"
psql -h -U -p -c "drop table schema.aux_tabla2_related3"

#Relleno de las auxiliares
psql -h -U -p -c "create table schema.aux_tabla2_related1 as select * from schema.tabla2_related1"
psql -h -U -p -c "create table schema.aux_tabla2_related2 as select * from schema.tabla2_related2"
psql -h -U -p -c "create table schema.aux_tabla2_related3 as select * from schema.tabla2_related3"

#Borrado de las relacionadas
psql -h -U -p -c "delete from schema.tabla2_related1"
psql -h -U -p -c "delete from schema.tabla2_related2"
psql -h -U -p -c "delete from schema.tabla2_related3"

#Borramos el contenido de las tablas deseadas
psql -h -U -p -c "delete from schema.dictionary"
psql -h -U -p -c "delete from schema.tabla4"
psql -h -U -p -c "delete from schema.tabla2"
psql -h -U -p -c "delete from schema.tabla1"

#Rellenamos las tablas deseadas
psql -h -U -p <  /tmp/fichero.dump
#Restauramos las relacionadas
psql -h -U -p -c "insert into schema.tabla2_related1 select * from schema.aux_tabla2_related1"
psql -h -U -p -c "insert into schema.tabla2_related2 select * from schema.aux_tabla2_related2"
psql -h -U -p -c "insert into schema.tabla2_related3 select * from schema.aux_tabla2_related3"


lunes, 5 de mayo de 2014

Problemas de recepción Wifi Dell XPS 9530

Si estando en modo batería, tenéis problemas de cobertura wifi con vuestro Wifi Dell XPS 9530. Probar a conectaros a la corriente.

Si enchufados los problemas desaparecen, es conveniente que cambiéis el modo en que funciona el adaptador inalámbrico.

En la siguiente ventana, probad con "Ahorro de Energía Bajo", si persisten los problemas cambiar a "Rendimiento máximo".



Activar sensor de iluminación en Dell XPS 9530

Para ahorrar batería o para no tener que modificar manualmente el brillo, podemos hacer uso del sensor de iluminación cuya activación está un poco oculta en las opciones de energía del equipo de Windows 8.