java/sql-vyuka/src/java/cz/frantovo/sql/vyuka/dao/PiskovisteDAO.java
author František Kučera <franta-hg@frantovo.cz>
Sat Jul 18 17:28:35 2009 +0200 (2009-07-18)
changeset 52 0eeae8c247cc
parent 51 bc821c6d090c
child 53 c06dfb1a2678
permissions -rw-r--r--
Lepší řešení #3 – uživatel může zadat neomezeně příkazů, které nevracejí výsledek.
franta-hg@16
     1
package cz.frantovo.sql.vyuka.dao;
franta-hg@16
     2
franta-hg@16
     3
import cz.frantovo.sql.vyuka.dao.VyukaSuperDAO.DATABAZE;
franta-hg@16
     4
import cz.frantovo.sql.vyuka.dto.Hlaska;
franta-hg@16
     5
import cz.frantovo.sql.vyuka.dto.Hlaska.Typ;
franta-hg@16
     6
import cz.frantovo.sql.vyuka.dto.Tabulka;
franta-hg@16
     7
import cz.frantovo.sql.vyuka.dto.Uzivatel;
franta-hg@16
     8
import cz.frantovo.sql.vyuka.dto.VysledekSQL;
franta-hg@16
     9
import java.sql.Connection;
franta-hg@16
    10
import java.sql.PreparedStatement;
franta-hg@16
    11
import java.sql.ResultSet;
franta-hg@16
    12
import java.sql.SQLException;
franta-hg@16
    13
import java.util.logging.Level;
franta-hg@16
    14
franta-hg@16
    15
/**
franta-hg@16
    16
 * Pro spouštění uživatelových příkazů.
franta-hg@16
    17
 * @author fiki
franta-hg@16
    18
 */
franta-hg@16
    19
public class PiskovisteDAO extends VyukaSuperDAO {
franta-hg@16
    20
franta-hg@18
    21
    private enum VLASTNOSTI {
franta-hg@18
    22
franta-hg@18
    23
        VYCHOZI_CESTA
franta-hg@18
    24
    }
franta-hg@16
    25
    TipyDAO tipy = new TipyDAO();
franta-hg@16
    26
    HistorieDAO historie = new HistorieDAO();
franta-hg@16
    27
franta-hg@16
    28
    public VysledekSQL vykonejSQL(String sql, Uzivatel uzivatel) {
franta-hg@16
    29
        VysledekSQL v = new VysledekSQL();
franta-hg@16
    30
        if (historie.ulozPrikaz(sql, uzivatel)) {
franta-hg@16
    31
franta-hg@16
    32
            Connection db = getSpojeni(DATABAZE.PISKOVISTE);
franta-hg@16
    33
            if (db == null) {
franta-hg@16
    34
                v.getHlasky().add(new Hlaska("Došlo k chybě spojení.", Typ.Chyba));
franta-hg@16
    35
            } else {
franta-hg@16
    36
                PreparedStatement ps = null;
franta-hg@16
    37
                ResultSet rs = null;
franta-hg@16
    38
                try {
franta-hg@18
    39
                    /**
franta-hg@19
    40
                     * Uživatelskému SQL příkazu předřadíme výchozí cestu (search_path).
franta-hg@18
    41
                     * Protože uživatelé si ji mohou měnit a kvůli recyklaci databázových zdrojů
franta-hg@18
    42
                     * by jeden uživatel mohl ovlivnit jiného.
franta-hg@18
    43
                     */
franta-hg@18
    44
                    if (getVlastnost(VLASTNOSTI.VYCHOZI_CESTA) != null) {
franta-hg@18
    45
                        sql = orizni(getVlastnost(VLASTNOSTI.VYCHOZI_CESTA)) + sql;
franta-hg@18
    46
                    }
franta-hg@18
    47
franta-hg@30
    48
                    long casPred = System.currentTimeMillis();
franta-hg@16
    49
                    ps = db.prepareStatement(sql);
franta-hg@17
    50
                    boolean isRS = ps.execute();
franta-hg@16
    51
franta-hg@17
    52
                    if (isRS) {
franta-hg@17
    53
                        rs = ps.getResultSet();
franta-hg@17
    54
                        v.getTabulky().add(zpracujVysledek(rs));
franta-hg@18
    55
                    }
franta-hg@16
    56
franta-hg@51
    57
                    /**
franta-hg@51
    58
                     * Ošetříme případ, kdy uživatel zadá SQL příkaz, který nevrací výsledkovou sadu.
franta-hg@51
    59
                     * Typicky nastavení výchozího schématu: SET search_path = '…';
franta-hg@51
    60
                     * Poznámka: jeden „SET search_path = '…'“ se obvykle předřazuje uživatelskému SQL (viz PiskovisteDAO.xml).
franta-hg@52
    61
                     */                    
franta-hg@52
    62
                    while (ps.getMoreResults() || ps.getUpdateCount() > -1) {
franta-hg@18
    63
                        rs = ps.getResultSet();
franta-hg@51
    64
                        if (rs == null) {
franta-hg@52
    65
                            /** Jedná se o „update count“. */
franta-hg@51
    66
                        } else {
franta-hg@51
    67
                            v.getTabulky().add(zpracujVysledek(rs));
franta-hg@51
    68
                        }
franta-hg@18
    69
                    }
franta-hg@30
    70
                    long dobaProvadeni = System.currentTimeMillis() - casPred;
franta-hg@18
    71
franta-hg@18
    72
                    /** Varování */
franta-hg@18
    73
                    if (v.getHlasky().size() < 1 && v.getTabulky().size() < 1) {
franta-hg@18
    74
                        v.getHlasky().add(new Hlaska("SQL příkaz proběhl, ale nevrátil žádná data.", Typ.Varovani));
franta-hg@18
    75
                    }
franta-hg@18
    76
franta-hg@18
    77
                    /** Varování */
franta-hg@18
    78
                    int pocitadloTabulek = 1;
franta-hg@18
    79
                    for (Tabulka t : v.getTabulky()) {
franta-hg@18
    80
                        if (t.getHodnoty().size() < 1) {
franta-hg@18
    81
                            v.getHlasky().add(new Hlaska("Tabulka " + pocitadloTabulek + "  je prázdná.", Typ.Varovani));
franta-hg@16
    82
                        }
franta-hg@18
    83
                        pocitadloTabulek++;
franta-hg@16
    84
                    }
franta-hg@16
    85
franta-hg@30
    86
                    v.getHlasky().add(new Hlaska("SQL příkaz byl proveden úspěšně, během " + dobaProvadeni + " ms.", Typ.OK));
franta-hg@18
    87
franta-hg@16
    88
                } catch (SQLException e) {
franta-hg@16
    89
                    log.log(Level.SEVERE, "SQL chyba při vykonávání uživatelského dotazu.", e);
franta-hg@16
    90
                    v.getHlasky().add(new Hlaska("Chybné SQL: " + e.getMessage(), Typ.Chyba));
franta-hg@16
    91
                } catch (Exception e) {
franta-hg@16
    92
                    log.log(Level.SEVERE, "Chyba při vykonávání uživatelského dotazu.", e);
franta-hg@16
    93
                    v.getHlasky().add(new Hlaska("Došlo k chybě dotazu.", Typ.Chyba));
franta-hg@16
    94
                } finally {
franta-hg@16
    95
                    zavri(db, ps, rs);
franta-hg@16
    96
                }
franta-hg@16
    97
            }
franta-hg@16
    98
franta-hg@44
    99
            /** Tip pro uživatele */
franta-hg@44
   100
            String tip = tipy.getTip();
franta-hg@44
   101
            if (tip != null) {
franta-hg@44
   102
                v.getHlasky().add(new Hlaska(tip, Typ.Tip, false));
franta-hg@44
   103
            }
franta-hg@16
   104
franta-hg@16
   105
        } else {
franta-hg@16
   106
            v.getHlasky().add(new Hlaska("Došlo k chybě historie.", Typ.Chyba));
franta-hg@16
   107
        }
franta-hg@16
   108
        return v;
franta-hg@16
   109
    }
franta-hg@17
   110
franta-hg@17
   111
    private Tabulka zpracujVysledek(ResultSet rs) throws SQLException {
franta-hg@17
   112
        Tabulka t = new Tabulka();
franta-hg@17
   113
franta-hg@17
   114
        int pocetSloupecku = rs.getMetaData().getColumnCount();
franta-hg@17
   115
        String[] zahlavi = new String[pocetSloupecku];
franta-hg@17
   116
        t.setZahlavi(zahlavi);
franta-hg@17
   117
        for (int i = 0; i < pocetSloupecku; i++) {
franta-hg@17
   118
            zahlavi[i] = rs.getMetaData().getColumnName(i + 1);
franta-hg@17
   119
        }
franta-hg@17
   120
franta-hg@17
   121
        while (rs.next()) {
franta-hg@17
   122
            Object[] hodnoty = new Object[pocetSloupecku];
franta-hg@17
   123
            for (int i = 0; i < pocetSloupecku; i++) {
franta-hg@17
   124
                hodnoty[i] = rs.getObject(i + 1);
franta-hg@17
   125
            }
franta-hg@17
   126
            t.getHodnoty().add(hodnoty);
franta-hg@17
   127
        }
franta-hg@17
   128
franta-hg@17
   129
        return t;
franta-hg@17
   130
    }
franta-hg@16
   131
}