root/java/sql-vyuka/src/java/cz/frantovo/sql/vyuka/dao/PiskovisteDAO.java @ 51:bc821c6d090c

Revision 51:bc821c6d090c, 5.5 KB (checked in by František Kučera <franta-hg@…>, 15 years ago)

Oprava #3 – uživatel může zadat příkaz, který nevrací výsledkovou sadu (typicky nastavení „search_path“), dříve se nezobrazovaly následné výsledky (tabulky) a proces procházení skončil.
Teď může uživatel zadar jeden příkaz, který nevrací výsledek a výsledky (tabulky) následujících dotazů se mu zobrazí správně.

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