PageRenderTime 80ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/src/cs236369/hw5/dal/Course.java

https://github.com/yroey/Manage-HW5
Java | 497 lines | 446 code | 41 blank | 10 comment | 59 complexity | fe4a24b00df0553f993a0990c6ef0e44 MD5 | raw file
  1. package cs236369.hw5.dal;
  2. import java.sql.Connection;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.util.ArrayList;
  7. import java.util.Collection;
  8. import java.util.HashMap;
  9. import java.util.Iterator;
  10. import java.util.regex.Pattern;
  11. import cs236369.hw5.Logger;
  12. import cs236369.hw5.dal.Utils;
  13. public class Course extends Base {
  14. public static String tableName = "courses";
  15. public String getTableName() {
  16. return tableName;
  17. }
  18. public Course(int id) {
  19. super(id);
  20. }
  21. public Course() {
  22. super();
  23. key = "name";
  24. }
  25. public Course(ResultSet rs) {
  26. super(rs);
  27. }
  28. public static Course[] getAll() throws SQLException{
  29. Connection conn = Utils.getConnection();
  30. PreparedStatement ps = conn.prepareStatement("SELECT * FROM courses");
  31. Logger.log(ps.toString());
  32. ResultSet rs = ps.executeQuery();
  33. ArrayList<Course> courses = new ArrayList<Course>();
  34. while(rs.next()) {
  35. courses.add(new Course(rs));
  36. }
  37. Course[] arrayCourses = new Course[courses.size()];
  38. courses.toArray(arrayCourses);
  39. Utils.closeConnection(rs, ps, conn);
  40. return arrayCourses;
  41. }
  42. @Override
  43. void setFieldTypes() {
  44. fieldsTypes.put("group_id", "int");
  45. fieldsTypes.put("name", "string");
  46. fieldsTypes.put("capacity", "int");
  47. fieldsTypes.put("credit_points", "int");
  48. fieldsTypes.put("description", "string");
  49. fieldsTypes.put("creator_id", "int");
  50. }
  51. public String getName() {
  52. return getStringField("name");
  53. }
  54. public int getCredit() {
  55. return getIntField("credit_points");
  56. }
  57. public static Course[] GetByIds(int[] ids) throws SQLException {
  58. if (ids == null || ids.length == 0){
  59. return new Course[0];
  60. }
  61. Connection conn = Utils.getConnection();
  62. PreparedStatement ps = null;
  63. ResultSet rs = null;
  64. StringBuilder stringIds = new StringBuilder();
  65. stringIds.append(ids[0]);
  66. for (int i = 1; i < ids.length; ++i)
  67. stringIds.append(", ").append(ids[i]);
  68. try {
  69. ps = conn.prepareStatement("SELECT * FROM courses WHERE id in (" + stringIds.toString() + ")");
  70. rs = ps.executeQuery();
  71. } catch (SQLException e) {
  72. // TODO Auto-generated catch block
  73. e.printStackTrace();
  74. }
  75. ArrayList<Course> courses = new ArrayList<Course>();
  76. while(rs.next()) {
  77. courses.add(new Course(rs));
  78. }
  79. Utils.closeConnection(rs, ps, conn);
  80. Course[] arrayCourses = new Course[courses.size()];
  81. courses.toArray(arrayCourses);
  82. return arrayCourses;
  83. }
  84. public Student[] getStudents() throws SQLException {
  85. Connection conn = Utils.getConnection();
  86. String query = "SELECT * FROM courses_students WHERE course_id = ?;";
  87. PreparedStatement ps = conn.prepareStatement(query);
  88. ps.setInt(1, getId());
  89. Logger.log(ps.toString());
  90. ResultSet rs = ps.executeQuery();
  91. ArrayList<Integer> ids = new ArrayList<Integer>();
  92. while(rs.next()) {
  93. ids.add(rs.getInt("course_id"));
  94. }
  95. int[] arrayIds = new int[ids.size()];
  96. for (int i=0; i < arrayIds.length; i++){
  97. arrayIds[i] = ids.get(i).intValue();
  98. }
  99. Utils.closeConnection(rs, ps, conn);
  100. return Student.GetByIds(arrayIds);
  101. }
  102. public Session[] getSessions() throws SQLException {
  103. Connection conn = Utils.getConnection();
  104. String query = "SELECT * FROM sessions WHERE course_id = ?";
  105. PreparedStatement ps = conn.prepareStatement(query);
  106. ps.setInt(1, getId());
  107. ResultSet rs = ps.executeQuery();
  108. ArrayList<Session> sessions = new ArrayList<Session>();
  109. while(rs.next()) {
  110. sessions.add(new Session(rs));
  111. }
  112. Session[] arraySessions = new Session[sessions.size()];
  113. sessions.toArray(arraySessions);
  114. Utils.closeConnection(rs, ps, conn);
  115. return arraySessions;
  116. }
  117. public static Course[] search(String name, boolean available) {
  118. try {
  119. return getAll();
  120. } catch (SQLException e) {
  121. // TODO Auto-generated catch block
  122. e.printStackTrace();
  123. }
  124. return new Course[0];
  125. }
  126. public static boolean doCoursesConflict(Course course1, Course course2) throws SQLException {
  127. for (Session session1 : course1.getSessions()) {
  128. for (Session session2 : course2.getSessions()) {
  129. if (Session.doSessionsConflict(session1, session2)) {
  130. return true;
  131. }
  132. }
  133. }
  134. return false;
  135. }
  136. public int getNumStudents() throws SQLException {
  137. Connection conn = Utils.getConnection();
  138. String query = "SELECT count(*) FROM courses_students WHERE course_id = ?;";
  139. PreparedStatement ps = conn.prepareStatement(query);
  140. ps.setInt(1, getId());
  141. Logger.log(ps.toString());
  142. ResultSet rs = ps.executeQuery();
  143. if (!rs.next()){
  144. Utils.closeConnection(rs, ps, conn);
  145. //ERROR
  146. }
  147. int ret = rs.getInt(1);
  148. Utils.closeConnection(rs, ps, conn);
  149. return ret;
  150. }
  151. public int getCapacity() {
  152. return getIntField("capacity");
  153. }
  154. static protected String[] getTokens(String query) {
  155. ArrayList<String> tokens = new ArrayList<String>();
  156. query = query.trim();
  157. int start_token = 0;
  158. int index = 0;
  159. boolean in_quote = false;
  160. while(index < query.length()) {
  161. if (query.substring(index, index + 1).equals("\"")) {
  162. if (in_quote) {
  163. tokens.add(query.substring(start_token, index));
  164. index++;
  165. start_token = index;
  166. in_quote = false;
  167. } else {
  168. if (start_token != index-1) {
  169. tokens.add(query.substring(start_token, index));
  170. }
  171. in_quote = true;
  172. start_token = ++index;
  173. }
  174. continue;
  175. }
  176. if (query.substring(index, index + 1).equals(" ") && !in_quote) {
  177. tokens.add(query.substring(start_token, index));
  178. start_token = ++index;
  179. continue;
  180. }
  181. ++index;
  182. }
  183. if (start_token < index) {
  184. tokens.add(query.substring(start_token, index));
  185. }
  186. String[] arrayTokens = new String[tokens.size()];
  187. tokens.toArray(arrayTokens);
  188. return arrayTokens;
  189. }
  190. protected static String fillQuery(HashMap<String, ArrayList<String>> tag_values, ArrayList<String> int_fields) {
  191. String query = "";
  192. for (String tag : tag_values.keySet()) {
  193. ArrayList<String> values = tag_values.get(tag);
  194. System.out.println("tag: " + tag);
  195. query += "(";
  196. for(int i = 0; i < values.size(); ++i) {
  197. if(tag.equals("full_text")){
  198. query += " (MATCH(name, description) AGAINST('" + values.get(i).replace("'", "\'") + "' IN BOOLEAN MODE)) ";
  199. continue;
  200. }
  201. query += "(";
  202. String[] tokens = getTokens(values.get(i).replace("'", "\'"));
  203. for (int j = 0; j < tokens.length; ++ j) {
  204. if (int_fields.contains(tag)) {
  205. double value;
  206. String str_value = tokens[j];
  207. String type = str_value.substring(0, 1);
  208. if (type.equals("<") || type.equals(">")) {
  209. str_value = str_value.substring(1);
  210. } else {
  211. type = "=";
  212. }
  213. try {
  214. value = Double.parseDouble(str_value);
  215. } catch(Exception e) {
  216. continue;
  217. }
  218. query += tag + type + value;
  219. } else {
  220. query += tag + " LIKE '%" + tokens[j] + "%'";
  221. }
  222. if (j + 1 != tokens.length) {
  223. query += " AND ";
  224. }
  225. }
  226. query += ")";
  227. if (i + 1 != values.size()) {
  228. query += " OR ";
  229. }
  230. }
  231. query += ") AND";
  232. }
  233. return query + " 1 = 1 ";
  234. }
  235. public static Course[] searchCourses(HashMap<String, ArrayList<String>> tag_values, Integer[] ids) throws SQLException {
  236. Connection connection = Utils.getConnection();
  237. PreparedStatement prepStmt = null;
  238. ResultSet rs = null;
  239. ArrayList<String> full_text_values = tag_values.get("full_text");
  240. String relevance = "(0 ";
  241. if (full_text_values != null) {
  242. for(String value: full_text_values) {
  243. relevance += "+ (MATCH(name, description) AGAINST('" + value.replace("'", "\'") + "' IN BOOLEAN MODE)) ";
  244. }
  245. }
  246. relevance += " )";
  247. String query = "SELECT *, " + relevance + " as relevance FROM courses WHERE ";
  248. ArrayList<String> int_fields = new ArrayList<String>();
  249. int_fields.add("credit_points");
  250. int_fields.add("group_id");
  251. int_fields.add("capacity");
  252. query += fillQuery(tag_values, int_fields);
  253. System.out.println("SEARCH QUERY IS: " + query);
  254. if (ids.length != 0) {
  255. query += " AND id IN (";
  256. for (int i = 0; i < ids.length -1; ++i) {
  257. query += ids[i] +", ";
  258. }
  259. query += ids[ids.length - 1] + ")";
  260. }
  261. query += " ORDER BY relevance DESC";
  262. System.out.println("FINAL SEARCH QUERY IS: " + query);
  263. try {
  264. prepStmt = connection.prepareStatement(query);
  265. rs = prepStmt.executeQuery();
  266. } catch (SQLException e) {
  267. // TODO Auto-generated catch block
  268. e.printStackTrace();
  269. Utils.closeConnection(rs, prepStmt, connection);
  270. return new Course[0];
  271. }
  272. ArrayList<Course> courses = new ArrayList<Course>();
  273. while(rs.next()) {
  274. courses.add(new Course(rs));
  275. }
  276. Utils.closeConnection(rs, prepStmt, connection);
  277. Course[] arrayCourses = new Course[courses.size()];
  278. courses.toArray(arrayCourses);
  279. return arrayCourses;
  280. }
  281. public static String[] getGroups() {
  282. return null;
  283. }
  284. public boolean delete(){
  285. Connection conn = Utils.getConnection();
  286. try
  287. {
  288. conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
  289. conn.setAutoCommit(false);
  290. String prepStmt = "DELETE FROM " + getTableName() + " WHERE id = ?;";
  291. PreparedStatement ps = null;
  292. ps = conn.prepareStatement(prepStmt);
  293. ps.setInt(1, id);
  294. Logger.log(ps.toString());
  295. ps.executeUpdate();
  296. ps = conn.prepareStatement("DELETE FROM courses_students WHERE course_id = ?");
  297. ps.setInt(1, id);
  298. ps.executeUpdate();
  299. ps = conn.prepareStatement("DELETE FROM sessions WHERE course_id = ?");
  300. ps.setInt(1, id);
  301. ps.executeUpdate();
  302. conn.commit();
  303. Utils.closeConnection(null, ps, conn);
  304. return true;
  305. }catch (SQLException e) {
  306. try
  307. {
  308. conn.rollback();
  309. }
  310. catch (SQLException e1)
  311. {
  312. // TODO Auto-generated catch block
  313. e1.printStackTrace();
  314. }
  315. // TODO Auto-generated catch block
  316. e.printStackTrace();
  317. }
  318. return false;
  319. }
  320. public boolean save(String sessions) {
  321. if (!validate()) {
  322. return false;
  323. }
  324. if (duplicate(this.key, (String)fieldsValues.get(this.key))){
  325. return false;
  326. }
  327. Connection conn = Utils.getConnection();
  328. try
  329. {
  330. conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
  331. conn.setAutoCommit(false);
  332. String prepStmt = "INSERT INTO " + getTableName() + " (" + fields.get(0);
  333. for (int i = 1 ; i < fields.size(); i++ ){
  334. prepStmt += " ," + fields.get(i);
  335. }
  336. prepStmt += ")";
  337. prepStmt += " VALUES ( ?";
  338. for (int i = 0 ; i < fieldsTypes.size() - 1 ; i++){
  339. prepStmt += ", ?";
  340. }
  341. prepStmt += ");";
  342. PreparedStatement ps = null;
  343. ps = conn.prepareStatement(prepStmt);
  344. Collection<String> ct = fieldsTypes.values();
  345. Iterator<String> itrT = ct.iterator();
  346. Collection<Object> cv = fieldsValues.values();
  347. Iterator<Object> itrV = cv.iterator();
  348. int i = 1;
  349. while(itrT.hasNext()){
  350. if(itrT.next().equals("string")){
  351. ps.setString(i,(String)itrV.next());
  352. }
  353. else{ //int
  354. ps.setInt(i, (Integer)itrV.next());
  355. }
  356. i++;
  357. }
  358. ps.executeUpdate();
  359. prepStmt = "SELECT * FROM courses WHERE name=?;";
  360. ps = conn.prepareStatement(prepStmt);
  361. ps.setString(1, getStringField("name"));
  362. ResultSet rs = ps.executeQuery();
  363. if (!rs.next()){
  364. //error
  365. }
  366. this.id = new Course(rs).getId();
  367. ArrayList<Session> allSessions = Session.registerSessions(sessions, this, conn);
  368. conn.commit();
  369. Utils.closeConnection(null, ps, conn);
  370. if (this.hasDuplicate()) {
  371. this.delete();
  372. return false;
  373. }
  374. if (this.doSessionsConflict(allSessions)) {
  375. this.delete();
  376. return false;
  377. }
  378. return true;
  379. }catch (SQLException e) {
  380. try
  381. {
  382. conn.rollback();
  383. }
  384. catch (SQLException e1)
  385. {
  386. // TODO Auto-generated catch block
  387. e1.printStackTrace();
  388. }
  389. }
  390. return false;
  391. }
  392. private boolean doSessionsConflict(ArrayList<Session> newCourseSessions)
  393. {
  394. Course[] allcourses = null;
  395. try
  396. {
  397. allcourses = Course.getAll();
  398. ArrayList<Session> allSessionsByGroup = new ArrayList<Session>();
  399. for (Course c : allcourses){
  400. if (c.getIntField("group_id") == this.getIntField("group_id") && c.getId() != this.id){
  401. Session[] sessions = c.getSessions();
  402. for (Session s: sessions){
  403. allSessionsByGroup.add(s);
  404. }
  405. }
  406. }
  407. for (Session s1 : newCourseSessions){
  408. for(Session s2: allSessionsByGroup){
  409. if (Session.doSessionsConflict(s1, s2)){
  410. return true;
  411. }
  412. }
  413. }
  414. }
  415. catch (SQLException e)
  416. {
  417. // TODO Auto-generated catch block
  418. e.printStackTrace();
  419. }
  420. return false;
  421. }
  422. public boolean hasDuplicate() {
  423. Connection conn = Utils.getConnection();
  424. PreparedStatement ps = null;
  425. ResultSet rs = null;
  426. try {
  427. ps = conn.prepareStatement("SELECT * FROM courses WHERE id != ? and name = ?");
  428. ps.setInt(1, getId());
  429. ps.setString(2, getStringField("name"));
  430. rs = ps.executeQuery();
  431. rs.last();
  432. return rs.getRow() == 1;
  433. } catch (SQLException e) {
  434. // TODO Auto-generated catch block
  435. e.printStackTrace();
  436. return false;
  437. } finally {
  438. Utils.closeConnection(rs, ps, conn);
  439. }
  440. }
  441. public boolean validate() {
  442. if (!Pattern.matches("^[a-zA-Z0-9 ]{1,32}$", getStringField("name"))) {
  443. return false;
  444. }
  445. if (!Pattern.matches("^[0-9]{1,12}$", new Integer(getIntField("group_id")).toString())) {
  446. return false;
  447. }
  448. if (!Pattern.matches("^[0-9]{1,12}$", new Integer(getIntField("capacity")).toString())) {
  449. return false;
  450. }
  451. if (!Pattern.matches("^[0-9]{1,12}$", new Integer(getIntField("credit_points")).toString())) {
  452. return false;
  453. }
  454. return true;
  455. }
  456. }