/[projects]/android/TrainInfoServiceGoogle/src/dk/thoerup/traininfoservice/StationDAO.java
ViewVC logotype

Diff of /android/TrainInfoServiceGoogle/src/dk/thoerup/traininfoservice/StationDAO.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1104 by torben, Tue Sep 21 20:10:46 2010 UTC revision 1105 by torben, Wed Sep 22 21:09:39 2010 UTC
# Line 1  Line 1 
1  package dk.thoerup.traininfoservice;  package dk.thoerup.traininfoservice;
2    
3  import java.sql.Connection;  import java.io.IOException;
4  import java.sql.PreparedStatement;  import java.util.ArrayList;
5  import java.sql.ResultSet;  import java.util.Collections;
6  import java.sql.SQLException;  import java.util.Comparator;
7  import java.sql.Statement;  import java.util.List;
8  import java.util.logging.Logger;  import java.util.logging.Logger;
9    
10  import javax.jdo.PersistenceManager;  import javax.jdo.PersistenceManager;
11    import javax.jdo.Query;
12    
13  import dk.thoerup.android.traininfo.common.StationBean;  import dk.thoerup.android.traininfo.common.StationBean;
14  import dk.thoerup.android.traininfo.common.StationBean.StationEntry;  import dk.thoerup.android.traininfo.common.StationBean.StationEntry;
15    import dk.thoerup.traininfoservice.geo.Geo;
16  import dk.thoerup.traininfoservice.jdo.JdoStationBean;  import dk.thoerup.traininfoservice.jdo.JdoStationBean;
17  import dk.thoerup.traininfoservice.jdo.PMF;  import dk.thoerup.traininfoservice.jdo.PMF;
18    
19  public class StationDAO {  public class StationDAO {
20          final static int LOCATION_LIMIT = 8;          final static int LOCATION_LIMIT = 8;
21          static final Logger logger = Logger.getLogger(StationDAO.class.getName());          static final Logger logger = Logger.getLogger(StationDAO.class.getName());
           
           
         private StationEntry convertSingleRow(ResultSet res) throws SQLException {  
                 StationEntry station = new StationEntry();  
   
                 station.setId( res.getInt(1) );  
                 station.setName( res.getString(2) );  
                 station.setLatitude( res.getDouble(3) );  
                 station.setLongitude( res.getDouble(4) );  
                 station.setRegional( res.getString(5) );  
                 station.setStrain( res.getString(6) );  
                 station.setMetro( res.getString(7) );  
                 station.setAddress( res.getString(8) );  
                 station.setCalcdist( (int)res.getDouble(9) );  
                   
                 station.setIsRegional( station.getRegional() != null );  
                 station.setIsStrain( station.getStrain() != null );  
                 station.setIsMetro( station.getMetro() != null );  
   
                 return station;  
         }  
22    
         private StationBean convertResultset(ResultSet res) throws SQLException {  
                 StationBean stations = new StationBean();  
                 while (res.next()) {  
                         stations.entries.add( convertSingleRow(res) );  
                 }  
                 return stations;  
   
         }  
23    
24            public StationEntry getById(int id)  {
         public JdoStationBean getById(int id) throws SQLException {  
25    
26                  PersistenceManager pm = null;                  PersistenceManager pm = null;
27                                    
28                  try {                  try {
29                          pm = PMF.get().getPersistenceManager();                          pm = PMF.get().getPersistenceManager();
30                          return pm.getObjectById(JdoStationBean.class, new Integer(id) );                          JdoStationBean bean =pm.getObjectById(JdoStationBean.class, new Integer(id) );
31                            return bean.toStationEntry();
32                  } finally {                  } finally {
33                          pm.close();                          pm.close();
34                  }                  }
35          }          }
36    
37          /*          /* damn that JDO sucks so we to the filtering in java-code */
38           * this code requires theses statements are run on database in order to do ILIKE searches against aliases (which is defines as array of varchar(64) )          public StationBean getByName(String searchname) {
39           *     create function rlike(text,text) returns bool as                  PersistenceManager pm = null;
40           *     'select $2 ilike $1' language sql strict immutable;                  
          *     create operator ~~~ (procedure = rlike, leftarg = text, rightarg = text, commutator = ~~);  
          */  
         public StationBean getByName(String name) throws SQLException {  
                 String SQL = "SELECT id,name,latitude,longitude,stationcode_fjrn,stationcode_stog, stationcode_metro, address, 0.0 " +  
                 "FROM trainstations " +  
                 "WHERE (name ILIKE ? OR ? ~~~ ANY(aliases)) AND enabled = true " +  
                 "ORDER BY name ";  
   
   
                 StationBean result;  
                 Connection conn = null;  
                 PreparedStatement stmt = null;  
                 ResultSet res = null;  
41                  try {                  try {
42                          conn = DBConnection.getConnection();                          pm = PMF.get().getPersistenceManager();
43                          stmt = conn.prepareStatement(SQL);                          
44                            
45                          stmt.setString(1, name + "%");                          
46                          stmt.setString(2, name + "%");                          Query q = pm.newQuery(JdoStationBean.class);
47                            q.setOrdering("name");                  
48                          res = stmt.executeQuery();                          List<JdoStationBean> beanList = (List<JdoStationBean>) q.execute();
49                          result = convertResultset(res);                          
50                            StationBean stationBean = new StationBean();
51                            
52                            searchname = searchname.toLowerCase();
53                            for(JdoStationBean bean : beanList) {
54                                    if (bean.getName().toLowerCase().startsWith(searchname)) {
55                                            stationBean.entries.add( bean.toStationEntry() );
56                                    } else {
57                                            for (String alias : bean.aliases ) {
58                                                    if (alias.toLowerCase().startsWith(searchname)) {
59                                                            stationBean.entries.add( bean.toStationEntry() );
60                                                    }
61                                            }
62                                    }
63                            }
64    
65                            return stationBean;                    
66                  } finally {                  } finally {
67                          if (res != null)                          pm.close();
                                 res.close();  
                         if (stmt != null)  
                                 stmt.close();  
                         if (conn!= null)  
                                 conn.close();  
68                  }                  }
                 return result;  
69          }          }
70    
         //the "hack" with max 0.4 degrees latitude and 0.75 degrees longitude is only valid since we only service danish trains,  
         // in denmark 0.4dg latitude ~ 44km, 0.75dg longitude ~ 47km  
71    
72          // the ultra fast method  (and only slightly inaccurate as long as we only cover a limited geographically area)          public StationBean getByLocation(double latitude, double longitude)  {
         // is using an aproximation of the length of 1 latitude degree and 1 longitude degree and just use pythagoras to  
         // calculate the distance:  
         //     sqrt( power(abs(latitude-?)*111320, 2) + power(abs(longitude-?)*63000,2) )::int as calcdist  
   
         public StationBean getByLocationWorker(double latitude, double longitude, boolean geolimit) throws SQLException {  
                   
                 String limitExpression = (geolimit == true) ? "AND abs(latitude-?)<0.4 AND abs(longitude-?)<0.75 " : "";  
73                                    
                 String SQL = "SELECT id,name,latitude,longitude,stationcode_fjrn,stationcode_stog, stationcode_metro, address, " +  
                         "earth_distance( earth_coord, ll_to_earth(?,?))::int AS calcdist " +  
                         "FROM trainstations " +  
                         "WHERE enabled = true " + limitExpression +  
                         "ORDER BY calcdist ASC " +  
                         "LIMIT " + LOCATION_LIMIT;  
   
74    
75                                    
76                  StationBean result;                  PersistenceManager pm = null;
                 Connection conn = null;  
                 PreparedStatement stmt = null;  
                 ResultSet res = null;  
                 try {  
                         conn = DBConnection.getConnection();  
                         stmt = conn.prepareStatement(SQL);  
                         stmt.setDouble(1, latitude);  
                         stmt.setDouble(2, longitude);  
                         if (geolimit == true) {  
                                 stmt.setDouble(3, latitude);  
                                 stmt.setDouble(4, longitude);  
                         }  
                         res = stmt.executeQuery();  
                         result = convertResultset(res);  
                   
                 } finally {  
                         if (res != null)  
                                 res.close();  
                         if (stmt != null)  
                                 stmt.close();  
                         if (conn!= null)  
                                 conn.close();  
                 }  
                 return result;  
         }  
           
         public StationBean getByLocation(double latitude, double longitude) throws SQLException {  
                 StationBean result = getByLocationWorker(latitude, longitude, true);  
77                                    
78                  if (result.entries.size() < LOCATION_LIMIT) { //failover                  try {
79                          logger.info("getByLocation failover: " +latitude + "," + longitude);                          pm = PMF.get().getPersistenceManager();
80                            List<JdoStationBean> beanList = (List<JdoStationBean>) pm.newQuery(JdoStationBean.class).execute();
81                            
82                            StationBean stationBean = new StationBean();                    
83                                                    
                         result = getByLocationWorker(latitude, longitude, false);  
                 }  
                   
                 return result;  
         }  
           
           
84    
85          public StationBean getByList(String list) throws SQLException {                          for(JdoStationBean bean : beanList) {
86                  String SQL = "SELECT id,name,latitude,longitude,stationcode_fjrn,stationcode_stog,stationcode_metro, address,0.0 " +                                  double meter = Geo.distanceKM(latitude, longitude, bean.getLatitude(), bean.getLongitude()) * 1000.0;
87                  "FROM trainstations " +                                  
88                  "WHERE id IN " + list + " AND enabled = true " +                                  bean.distance = (int) meter;
89                  "ORDER BY name ";                          }
90                            
91    
92                  Connection conn = null;                          Collections.sort(beanList, new Comparator<JdoStationBean>() {
93                  Statement stmt = null;                                  @Override
94                  ResultSet res = null;                                  public int compare(JdoStationBean o1, JdoStationBean o2) {
95                  StationBean result;                                          if (o1.distance < o2.distance) {
96                                                    return -1;
97                                            } else if (o1.distance > o2.distance) {
98                                                    return 1;
99                                            } else {
100                                                    return 0;
101                                            }
102                                    }
103                            });
104                            
105                            for (int i=0; i<LOCATION_LIMIT && i<beanList.size(); i++) {
106                                    stationBean.entries.add( beanList.get(i).toStationEntry() );
107                            }
108    
109                  try {                          return stationBean;                    
                         conn = DBConnection.getConnection();  
                         stmt = conn.createStatement();  
                         res = stmt.executeQuery(SQL);  
                         result = convertResultset(res);  
110                  } finally {                  } finally {
111                          if (res != null)                          pm.close();
                                 res.close();  
                         if (stmt != null)  
                                 stmt.close();  
                         if (conn!= null)  
                                 conn.close();  
112                  }                  }
   
                 return result;  
   
113          }          }
114          public static String getStationName(int stationID) {          
                 String station = "";  
115    
116                  Connection conn = null;          public StationBean getByList(String list)  {
117                    PersistenceManager pm = null;
118                    
119                  try {                  try {
120                          conn = DBConnection.getConnection();                          String parts[] = list.split(",");
121                          Statement stmt = conn.createStatement();                          
122                          ResultSet rs = stmt.executeQuery("SELECT name FROM trainstations WHERE id=" + stationID);                          StringBuilder filter = new StringBuilder();
123                          if (rs.next()) {                          
124                                  station = rs.getString(1);                          for(String part : parts)  {
125                                    if (filter.length() > 0) {
126                                            filter.append( " || " );
127                                    }
128                                    filter.append("id == ").append(part);
129                            }                      
130                            
131                            //String filter = "id == 10 || id == 82"; //TODO: build filter
132                            
133                            pm = PMF.get().getPersistenceManager();
134                            Query q = pm.newQuery(JdoStationBean.class);
135                            q.setFilter( filter.toString() );
136                            q.setOrdering("name");
137                            
138                            List<JdoStationBean> beanList = (List<JdoStationBean>) q.execute();
139                            
140                            StationBean stationBean = new StationBean();
141                            
142                            for(JdoStationBean bean : beanList) {
143                                    stationBean.entries.add( bean.toStationEntry() );
144                          }                          }
145    
146                  } catch (Exception e) {                          return stationBean;                    
147                  } finally {                  } finally {
148                          try {                          pm.close();
                                 if (conn != null && !conn.isClosed())  
                                         conn.close();  
                         } catch (Exception e) {}  
149                  }                  }
150    
                 return station;  
151          }          }
152    
         public int getIdByName(String name) throws SQLException {  
                 String SQL = "SELECT id,name,latitude,longitude,stationcode_fjrn,stationcode_stog, stationcode_metro, address, 0.0 " +  
                 "FROM trainstations " +  
                 "WHERE name = ?  AND enabled = true " +  
                 "LIMIT 1 ";  
153    
154                  StationBean result;          public int getIdByName(String name)  {
155                  Connection conn = null;                  
156                  PreparedStatement stmt = null;                  List<JdoStationBean> beanList = null;
157                  ResultSet res = null;                  
158                    PersistenceManager pm = null;
159                    
160                  try {                  try {
161                          conn = DBConnection.getConnection();                          
162                          stmt = conn.prepareStatement(SQL);                          String filter = " name == '" + name + "'";
163                            
164                          stmt.setString(1, name );                          pm = PMF.get().getPersistenceManager();
165                            Query q = pm.newQuery(JdoStationBean.class);
166                          res = stmt.executeQuery();                          q.setFilter(filter);
167                          result = convertResultset(res);                          
168                            beanList = (List<JdoStationBean>) q.execute();
169                            
170                            StationBean stationBean = new StationBean();
171                            
172                            for(JdoStationBean bean : beanList) {
173                                    stationBean.entries.add( bean.toStationEntry() );
174                            }
175                            
176                  } finally {                  } finally {
177                          if (res != null)                          pm.close();
                                 res.close();  
                         if (stmt != null)  
                                 stmt.close();  
                         if (conn!= null)  
                                 conn.close();  
178                  }                  }
179    
180                  if (result.entries.size() == 1) {                  if ( beanList != null && beanList.size()  == 1) {
181                          return result.entries.get(0).getId();                          return (int) beanList.get(0).getId();
182                  } else {                  } else {
183                          return -1;                          return -1;
184                  }                  }
185          }          }
186            
187            @SuppressWarnings("unchecked")
188            public int saveStations(StationBean stationBean) throws IOException {
189                    PersistenceManager pm = null;
190                    
191                    try {
192                            pm = PMF.get().getPersistenceManager();
193                            
194                            List oldEntries = (List) pm.newQuery(JdoStationBean.class).execute();
195                            pm.deletePersistentAll(oldEntries);
196                            
197                            List<JdoStationBean> jdoList = new ArrayList<JdoStationBean>();
198                            for (StationEntry station : stationBean.entries) {
199                                    JdoStationBean jdoBean = JdoStationBean.fromStationEntry(station);
200                                    
201                                    jdoList.add(jdoBean);
202                                    
203                            }
204                            pm.makePersistentAll(jdoList);
205                            
206                            return jdoList.size();
207                            
208                    } finally {
209                            pm.close();
210                    }
211            }
212            
213  }  }

Legend:
Removed from v.1104  
changed lines
  Added in v.1105

  ViewVC Help
Powered by ViewVC 1.1.20