/[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

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

Legend:
Removed from v.997  
changed lines
  Added in v.1106

  ViewVC Help
Powered by ViewVC 1.1.20