810 |
810 |
811 return true; |
811 return true; |
812 } |
812 } |
813 } |
813 } |
814 |
814 |
815 /** |
815 /** |
816 * Inserts a row that has been inserted into the given |
816 * Inserts a row that has been inserted into the given |
817 * <code>CachedRowSet</code> object into the data source from which |
817 * <code>CachedRowSet</code> object into the data source from which |
818 * the rowset is derived, returning <code>false</code> if the insertion |
818 * the rowset is derived, returning <code>false</code> if the insertion |
819 * was successful. |
819 * was successful. |
820 * |
820 * |
821 * @param crs the <code>CachedRowSet</code> object that has had a row inserted |
821 * @param crs the <code>CachedRowSet</code> object that has had a row inserted |
822 * and to whose underlying data source the row will be inserted |
822 * and to whose underlying data source the row will be inserted |
823 * @param pstmt the <code>PreparedStatement</code> object that will be used |
823 * @param pstmt the <code>PreparedStatement</code> object that will be used |
824 * to execute the insertion |
824 * to execute the insertion |
825 * @return <code>false</code> to indicate that the insertion was successful; |
825 * @return <code>false</code> to indicate that the insertion was successful; |
826 * <code>true</code> otherwise |
826 * <code>true</code> otherwise |
827 * @throws SQLException if a database access error occurs |
827 * @throws SQLException if a database access error occurs |
828 */ |
828 */ |
829 private boolean insertNewRow(CachedRowSet crs, |
829 private boolean insertNewRow(CachedRowSet crs, |
830 PreparedStatement pstmt, CachedRowSetImpl crsRes) throws SQLException { |
830 PreparedStatement pstmt, CachedRowSetImpl crsRes) throws SQLException { |
831 int i = 0; |
831 |
832 int icolCount = crs.getMetaData().getColumnCount(); |
832 boolean returnVal = false; |
833 |
833 |
834 boolean returnVal = false; |
834 try (PreparedStatement pstmtSel = con.prepareStatement(selectCmd, |
835 PreparedStatement pstmtSel = con.prepareStatement(selectCmd, |
835 ResultSet.TYPE_SCROLL_SENSITIVE, |
836 ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); |
836 ResultSet.CONCUR_READ_ONLY); |
837 ResultSet rs, rs2 = null; |
837 ResultSet rs = pstmtSel.executeQuery(); |
838 DatabaseMetaData dbmd = con.getMetaData(); |
838 ResultSet rs2 = con.getMetaData().getPrimaryKeys(null, null, |
839 rs = pstmtSel.executeQuery(); |
839 crs.getTableName()) |
840 String table = crs.getTableName(); |
840 ) { |
841 rs2 = dbmd.getPrimaryKeys(null, null, table); |
841 |
842 String [] primaryKeys = new String[icolCount]; |
842 ResultSetMetaData rsmd = crs.getMetaData(); |
843 int k = 0; |
843 int icolCount = rsmd.getColumnCount(); |
844 while(rs2.next()) { |
844 String[] primaryKeys = new String[icolCount]; |
845 String pkcolname = rs2.getString("COLUMN_NAME"); |
845 int k = 0; |
846 primaryKeys[k] = pkcolname; |
846 while (rs2.next()) { |
847 k++; |
847 primaryKeys[k] = rs2.getString("COLUMN_NAME"); |
848 } |
848 k++; |
849 |
849 } |
850 if(rs.next()) { |
850 |
851 for(int j=0;j<primaryKeys.length;j++) { |
851 if (rs.next()) { |
852 if(primaryKeys[j] != null) { |
852 for (String pkName : primaryKeys) { |
853 if(crs.getObject(primaryKeys[j]) == null){ |
853 if (!isPKNameValid(pkName, rsmd)) { |
854 break; |
854 |
855 } |
855 /* We came here as one of the the primary keys |
856 String crsPK = (crs.getObject(primaryKeys[j])).toString(); |
856 * of the table is not present in the cached |
857 String rsPK = (rs.getObject(primaryKeys[j])).toString(); |
857 * rowset object, it should be an autoincrement column |
858 if(crsPK.equals(rsPK)) { |
858 * and not included while creating CachedRowSet |
859 returnVal = true; |
859 * Object, proceed to check for other primary keys |
860 this.crsResolve.moveToInsertRow(); |
860 */ |
861 for(i = 1; i <= icolCount; i++) { |
861 continue; |
862 String colname = (rs.getMetaData()).getColumnName(i); |
862 } |
863 if(colname.equals(primaryKeys[j])) |
863 |
864 this.crsResolve.updateObject(i,rsPK); |
864 Object crsPK = crs.getObject(pkName); |
865 else |
865 if (crsPK == null) { |
866 this.crsResolve.updateNull(i); |
866 /* |
867 } |
867 * It is possible that the PK is null on some databases |
868 this.crsResolve.insertRow(); |
868 * and will be filled in at insert time (MySQL for example) |
869 this.crsResolve.moveToCurrentRow(); |
869 */ |
870 } |
870 break; |
871 } |
871 } |
872 } |
872 |
873 } |
873 String rsPK = rs.getObject(pkName).toString(); |
874 if(returnVal) |
874 if (crsPK.toString().equals(rsPK)) { |
875 return returnVal; |
875 returnVal = true; |
876 |
876 this.crsResolve.moveToInsertRow(); |
877 try { |
877 for (int i = 1; i <= icolCount; i++) { |
878 for (i = 1; i <= icolCount; i++) { |
878 String colname = (rs.getMetaData()).getColumnName(i); |
879 Object obj = crs.getObject(i); |
879 if (colname.equals(pkName)) |
880 if (obj != null) { |
880 this.crsResolve.updateObject(i,rsPK); |
881 pstmt.setObject(i, obj); |
881 else |
882 } else { |
882 this.crsResolve.updateNull(i); |
883 pstmt.setNull(i,crs.getMetaData().getColumnType(i)); |
883 } |
884 } |
884 this.crsResolve.insertRow(); |
885 } |
885 this.crsResolve.moveToCurrentRow(); |
886 |
886 } |
887 i = pstmt.executeUpdate(); |
887 } |
888 return false; |
888 } |
889 |
889 |
890 } catch (SQLException ex) { |
890 if (returnVal) { |
891 /** |
891 return returnVal; |
892 * Cursor will come here if executeUpdate fails. |
892 } |
893 * There can be many reasons why the insertion failed, |
893 |
894 * one can be violation of primary key. |
894 try { |
895 * Hence we cannot exactly identify why the insertion failed |
895 for (int i = 1; i <= icolCount; i++) { |
896 * Present the current row as a null row to the user. |
896 Object obj = crs.getObject(i); |
897 **/ |
897 if (obj != null) { |
898 this.crsResolve.moveToInsertRow(); |
898 pstmt.setObject(i, obj); |
899 |
899 } else { |
900 for(i = 1; i <= icolCount; i++) { |
900 pstmt.setNull(i,crs.getMetaData().getColumnType(i)); |
901 this.crsResolve.updateNull(i); |
901 } |
902 } |
902 } |
903 |
903 |
904 this.crsResolve.insertRow(); |
904 pstmt.executeUpdate(); |
905 this.crsResolve.moveToCurrentRow(); |
905 return false; |
906 |
906 |
907 return true; |
907 } catch (SQLException ex) { |
908 } |
908 /* |
909 } |
909 * Cursor will come here if executeUpdate fails. |
|
910 * There can be many reasons why the insertion failed, |
|
911 * one can be violation of primary key. |
|
912 * Hence we cannot exactly identify why the insertion failed, |
|
913 * present the current row as a null row to the caller. |
|
914 */ |
|
915 this.crsResolve.moveToInsertRow(); |
|
916 |
|
917 for (int i = 1; i <= icolCount; i++) { |
|
918 this.crsResolve.updateNull(i); |
|
919 } |
|
920 |
|
921 this.crsResolve.insertRow(); |
|
922 this.crsResolve.moveToCurrentRow(); |
|
923 |
|
924 return true; |
|
925 } |
|
926 } |
|
927 } |
910 |
928 |
911 /** |
929 /** |
912 * Deletes the row in the underlying data source that corresponds to |
930 * Deletes the row in the underlying data source that corresponds to |
913 * a row that has been deleted in the given <code> CachedRowSet</code> object |
931 * a row that has been deleted in the given <code> CachedRowSet</code> object |
914 * and returns <code>false</code> if the deletion was successful. |
932 * and returns <code>false</code> if the deletion was successful. |