2727import java .io .File ;
2828import java .text .SimpleDateFormat ;
2929import java .util .ArrayList ;
30+ import java .util .Arrays ;
3031import java .util .Date ;
3132import java .util .Dictionary ;
3233import java .util .List ;
@@ -641,71 +642,86 @@ public JSObject prepareSQL(String statement, ArrayList<Object> values, Boolean f
641642 String stmtType = statement .replaceAll ("\n " , "" ).trim ().substring (0 , 6 ).toUpperCase ();
642643 SupportSQLiteStatement stmt = null ;
643644 String sqlStmt = statement ;
644- String retMode = returnMode ;
645+ String retMode ;
645646 JSArray retValues = new JSArray ();
646647 JSObject retObject = new JSObject ();
647648 String colNames = "" ;
648649 long initLastId = (long ) -1 ;
649- boolean isReturning = sqlStmt .toUpperCase ().contains ("RETURNING" );
650+ /* if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU) {
651+ retMode = returnMode;
652+ throw new Exception(retMode +"Not implemented for above TIRAMISU");
653+ } else {
654+
655+ */
656+ retMode = returnMode ;
657+ if (!retMode .equals ("no" )) {
658+ retMode = "wA" + retMode ;
659+ }
660+ // }
661+ if (retMode .equals ("no" ) || retMode .substring (0 , Math .min (retMode .length (), 2 )).equals ("wA" )) {
662+ // get the statement and the returning column names
663+ try {
664+ JSObject stmtObj = getStmtAndRetColNames (sqlStmt , retMode );
665+ sqlStmt = stmtObj .getString ("stmt" , sqlStmt );
666+ colNames = stmtObj .getString ("names" ,"" );
667+ } catch (JSONException e ) {
668+ throw new Exception (e .getMessage ());
669+ }
670+ }
650671 try {
651- if (!fromJson && stmtType .equals ("DELETE" )) {
652- sqlStmt = deleteSQL (this , statement , values );
653- }
654- if (isReturning && Build .VERSION .SDK_INT > Build .VERSION_CODES .TIRAMISU ) {
655- throw new Exception ("Not implemented for above TIRAMISU" );
656- }
657- if (isReturning ) {
658- // get the lastID
659- initLastId = _uSqlite .dbLastId (_db );
660- // get the statement and the returning column names
661- JSObject stmtObj = getStmtAndRetColNames (sqlStmt );
662- sqlStmt = stmtObj .getString ("stmt" );
663- colNames = stmtObj .getString ("names" );
664- }
665- if (sqlStmt != null ) {
672+ if (!fromJson && stmtType .equals ("DELETE" )) {
673+ sqlStmt = deleteSQL (this , sqlStmt , values );
674+ }
675+ if (sqlStmt != null ) {
666676 stmt = _db .compileStatement (sqlStmt );
667- } else {
668- throw new Exception ("sqlStmt is null" );
669- }
670- if (values != null && values .size () > 0 ) {
671- // retMode = "no";
672- Object [] valObj = new Object [values .size ()];
673- for (int i = 0 ; i < values .size (); i ++) {
674- if (values .get (i ) == null ) {
675- valObj [i ] = null ;
676- } else if (JSONObject .NULL == values .get (i )) {
677- valObj [i ] = null ;
678- } else {
679- valObj [i ] = values .get (i );
680- }
681- }
682- SimpleSQLiteQuery .bind (stmt , valObj );
677+ } else {
678+ throw new Exception ("sqlStmt is null" );
679+ }
680+ if (values != null && values .size () > 0 ) {
681+ // retMode = "no";
682+ Object [] valObj = new Object [values .size ()];
683+ for (int i = 0 ; i < values .size (); i ++) {
684+ if (values .get (i ) == null ) {
685+ valObj [i ] = null ;
686+ } else if (JSONObject .NULL == values .get (i )) {
687+ valObj [i ] = null ;
688+ } else {
689+ valObj [i ] = values .get (i );
690+ }
691+ }
692+ SimpleSQLiteQuery .bind (stmt , valObj );
693+ }
694+ initLastId = _uSqlite .dbLastId (_db );
695+ if (stmtType .equals ("INSERT" )) {
696+ stmt .executeInsert ();
697+ } else {
698+ if (retMode .startsWith ("wA" ) && colNames .length () > 0 && stmtType .equals ("DELETE" )) {
699+ retValues = getUpdDelReturnedValues (this , sqlStmt , colNames );
683700 }
701+ stmt .executeUpdateDelete ();
702+ }
703+ Long lastId = _uSqlite .dbLastId (_db );
704+ if (retMode .startsWith ("wA" ) && colNames .length () > 0 ) {
684705 if (stmtType .equals ("INSERT" )) {
685- stmt .executeInsert ();
686- } else {
687- if (isReturning && stmtType .equals ("DELETE" )) {
688- isReturning = false ;
689- retValues = getUpdDelReturnedValues (this , sqlStmt , colNames );
706+ String tableName = extractTableName (sqlStmt );
707+ if (tableName != null ) {
708+ retValues = getInsertReturnedValues (this , colNames , tableName , initLastId , lastId , retMode );
690709 }
691- stmt .executeUpdateDelete ();
710+ } else if (stmtType .equals ("UPDATE" )) {
711+ retValues = getUpdDelReturnedValues (this , sqlStmt , colNames );
692712 }
693- Long lastId = _uSqlite .dbLastId (_db );
694- if (isReturning ) {
695- if (stmtType .equals ("INSERT" )) {
696- String tableName = extractTableName (sqlStmt );
697- if (tableName != null ) {
698- if (retMode .equals ("one" ) || retMode .equals ("all" )) {
699- retValues = getInsertReturnedValues (this , colNames , tableName , initLastId , lastId , retMode );
700- }
701- }
702- } else if (stmtType .equals ("UPDATE" )) {
703- retValues = getUpdDelReturnedValues (this , sqlStmt , colNames );
704- }
713+ }
714+ /*
715+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU) {
716+
717+ if (retMode.startsWith("one") || retMode.startsWith("all")) {
718+ throw new Exception("returnMode : " + retMode + "Not implemented for above TIRAMISU");
705719 }
706- retObject .put ("lastId" , lastId );
707- retObject .put ("values" , retValues );
708- return retObject ;
720+ }
721+ */
722+ retObject .put ("lastId" , lastId );
723+ retObject .put ("values" , retValues );
724+ return retObject ;
709725 } catch (Exception e ) {
710726 throw new Exception (e .getMessage ());
711727 } finally {
@@ -715,18 +731,113 @@ public JSObject prepareSQL(String statement, ArrayList<Object> values, Boolean f
715731 }
716732 }
717733
718- private JSObject getStmtAndRetColNames (String sqlStmt ) {
734+ private JSObject getStmtAndRetColNames (String sqlStmt , String retMode ) throws JSONException {
719735 JSObject retObj = new JSObject ();
720- int idx = sqlStmt .toUpperCase ().indexOf ("RETURNING" );
721- String retStmt = sqlStmt .substring (0 , idx - 1 ) + ";" ;
722- String names = sqlStmt .substring (idx + 9 );
723- String retNames = names ;
724- if (names .contains (";" )) retNames = names .substring (0 , names .length () - 1 ).trim ();
725- retObj .put ("stmt" , retStmt );
726- retObj .put ("names" , retNames );
736+ JSObject retIsReturning = isReturning (sqlStmt );
737+ Boolean isReturning = retIsReturning .getBoolean ("isReturning" );
738+ String stmt = retIsReturning .getString ("stmt" );
739+ String suffix = retIsReturning .getString ("names" );
740+ retObj .put ("stmt" ,stmt );
741+ retObj .put ("names" ,"" );
742+
743+ if (isReturning && retMode .startsWith ("wA" )) {
744+
745+ String lowercaseSuffix = suffix != null ? suffix .toLowerCase () : "" ;
746+ int returningIndex = lowercaseSuffix .indexOf ("returning" );
747+ if (returningIndex != -1 ) {
748+ String substring = suffix .substring (returningIndex + "returning" .length ());
749+ String names = substring .trim ();
750+ if (names .endsWith (";" )) {
751+ retObj .put ("names" , names .substring (0 , names .length () - 1 ));
752+ }
753+ }
754+ }
727755 return retObj ;
728756 }
729757
758+ private JSObject isReturning (String sqlStmt ) {
759+ JSObject retObj = new JSObject ();
760+
761+ String stmt = sqlStmt .replace ("\n " , "" ).trim ();
762+ if (stmt .endsWith (";" )) {
763+ // Remove the suffix
764+ stmt = stmt .substring (0 , stmt .length () - 1 ).trim ();
765+ }
766+ retObj .put ("isReturning" ,false );
767+ retObj .put ("stmt" ,stmt );
768+ retObj .put ("names" ,"" );
769+
770+ switch (stmt .substring (0 , Math .min (stmt .length (), 6 )).toUpperCase ()) {
771+ case "INSERT" :
772+ int valuesIndex = stmt .toUpperCase ().indexOf ("VALUES" );
773+ if (valuesIndex != -1 ) {
774+
775+ int closingParenthesisIndex = -1 ;
776+
777+ for (int i = stmt .length () - 1 ; i >= valuesIndex ; i --) {
778+ if (stmt .charAt (i ) == ')' ) {
779+ closingParenthesisIndex = i ;
780+ break ;
781+ }
782+ }
783+ if (closingParenthesisIndex != -1 ) {
784+ String stmtString = stmt .substring (0 , closingParenthesisIndex + 1 ).trim () + ";" ;
785+ String resultString = stmt .substring (closingParenthesisIndex + 1 ).trim ();
786+ if (resultString .length () > 0 && !resultString .endsWith (";" )) {
787+ resultString += ";" ;
788+ }
789+ if (resultString .toLowerCase ().contains ("returning" )) {
790+ retObj .put ("isReturning" , true );
791+ retObj .put ("stmt" , stmtString );
792+ retObj .put ("names" , resultString );
793+ }
794+ }
795+ }
796+ return retObj ;
797+ case "DELETE" :
798+ case "UPDATE" :
799+ String [] words = stmt .split ("\\ s+" );
800+ List <String > wordsBeforeReturning = new ArrayList <>();
801+ List <String > returningString = new ArrayList <>();
802+
803+ boolean isReturningOutsideMessage = false ;
804+ for (String word : words ) {
805+ if (word .toLowerCase ().equals ("returning" )) {
806+ isReturningOutsideMessage = true ;
807+ // Include "RETURNING" and the words after it in returningString
808+ returningString .add (word );
809+ returningString .addAll (wordsAfter (word , words ));
810+ break ;
811+ }
812+ wordsBeforeReturning .add (word );
813+ }
814+
815+ if (isReturningOutsideMessage ) {
816+ String joinedWords = String .join (" " , wordsBeforeReturning ) + ";" ;
817+ String joinedReturningString = String .join (" " , returningString );
818+ if (joinedReturningString .length () > 0 && !joinedReturningString .endsWith (";" )) {
819+ joinedReturningString += ";" ;
820+ }
821+ retObj .put ("isReturning" ,true );
822+ retObj .put ("stmt" ,joinedWords );
823+ retObj .put ("names" ,joinedReturningString );
824+ return retObj ;
825+ } else {
826+ return retObj ;
827+ }
828+ default :
829+ return retObj ;
830+ }
831+ }
832+ private List <String > wordsAfter (String word , String [] words ) {
833+ List <String > mWords = Arrays .asList (words );
834+ int index = mWords .indexOf (word );
835+ if (index == -1 ) {
836+ return new ArrayList <>();
837+ }
838+ List <String > retWords = new ArrayList <>(mWords .subList (index + 1 , mWords .size ()));
839+ return retWords ;
840+ }
730841 private JSArray getInsertReturnedValues (Database mDB , String colNames , String tableName , Long iLastId , Long lastId , String rMode )
731842 throws Exception {
732843 JSArray retVals = new JSArray ();
@@ -735,10 +846,10 @@ private JSArray getInsertReturnedValues(Database mDB, String colNames, String ta
735846 StringBuilder sbQuery = new StringBuilder ("SELECT " ).append (colNames ).append (" FROM " );
736847
737848 sbQuery .append (tableName ).append (" WHERE " ).append ("rowid " );
738- if (rMode .equals ("one " )) {
849+ if (rMode .equals ("wAone " )) {
739850 sbQuery .append ("= " ).append (sLastId );
740851 }
741- if (rMode .equals ("all " )) {
852+ if (rMode .equals ("wAall " )) {
742853 sbQuery .append ("BETWEEN " ).append (sLastId ).append (" AND " ).append (lastId );
743854 }
744855 sbQuery .append (";" );
@@ -1069,6 +1180,8 @@ public JSObject exportToJson(String mode, Boolean isEncrypted) throws Exception
10691180 Date date = new Date ();
10701181 long syncTime = date .getTime () / 1000L ;
10711182 toJson .setLastExportDate (this , syncTime );
1183+ } else {
1184+ throw new Exception ("No sync_table available" );
10721185 }
10731186 // launch the export process
10741187 JsonSQLite retJson = toJson .createExportObject (this , inJson );
0 commit comments