Subscribe for automatic updates: RSS icon RSS

Login icon Sign in for full access | Help icon Help
Advanced search

Pages: [1]
  Reply  |  Print  
Author Topic: base.stringtokenizer split a String by word  (Read 14006 times)
ORGA-SOFT B.
Posts: 34


« on: May 22, 2018, 03:17:24 pm »

Hello community,

we try to split a STRING by the word "AND". Because we wan't to split the String returned by a construct statement.

So if we try this with the following code:

LET strtok = base.stringtokenizer.CREATE(buf.toString(), "AND")

The String is splitted by "A", "N", and "D" so can you tell us what is the correct Syntax to split by a whole word.


Thanks
ORGA-SOFT Backnang
Sebastien F.
Four Js
Posts: 545


« Reply #1 on: May 22, 2018, 04:14:39 pm »

Hello,

The StringTokenizer accepts a list of single-char separators, as described in

http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_ClassStringTokenizer_create.html

Parsing SQL is not that easy:

You can have the AND characters in a string literal:

  colname = 'ANDERSON'

Can you please explain why you need to parse the SQL produced by CONSTRUCT?

Seb
ORGA-SOFT B.
Posts: 34


« Reply #2 on: May 22, 2018, 04:28:36 pm »

Hello Sebastien,

thanks for your answer. Perhabs we are looking in the wrong direction.
We have several input fields and we try to modify the construnct so when a user put in a value in a field we are looking forward to make a matches search and not  =

for example user put Jo in the field we want to search like 'Jo*' not only 'Jo' any ideas?

Thanks.
Sebastien F.
Four Js
Posts: 545


« Reply #3 on: May 22, 2018, 05:01:48 pm »

I see no easy way to do that.

Adding a * at the end of the entered value depends on the field type:

You don't want to do add it for numeric or date/time fields.

Maybe use some generic function in all AFTER FIELD of the char/varchar fields, to add the * at the end of the input buffer if not there, so the end user sees it.

Code
  1.    CONSTRUCT BY NAME sql ON id, name
  2.        AFTER FIELD name
  3.           CALL add_star()
  4.    END CONSTRUCT
  5.  
  6. ...
  7.  
  8. FUNCTION add_star()
  9.    DEFINE v STRING
  10.    LET v = fgl_dialog_getBuffer()
  11.    IF v NOT LIKE "%*" THEN
  12.       CALL fgl_dialog_setBuffer( v || "*" )
  13.    END IF
  14. END FUNCTION
  15.  

But what if the end user wants to distinguish "Jo" from "John" and "Johan"?

So first I would teach end users how to use the CONSTRUCT syntax
http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_Construct_004.html

If they are not happy with CONSTRUCT, implement an option to have another query dialog like:

https://github.com/FourjsGenero/fgl_query_dialog

?

Seb
Reuben B.
Four Js
Posts: 1126


« Reply #4 on: May 23, 2018, 01:50:29 am »

For the original question, the base.StringBuffer.getIndexOf documentation has an example parsing a string by a word http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_ClassStringBuffer_getIndexOf.html.  The getIndexOf and subString methods available in both String and StringBuffer would allow you to attempt to do what you are attempting to do. 

getIndexOf(" AND ",pos) would be better than getIndexOf("AND",pos), but you have to be aware that even " AND " could be part of the entered value, as in "SMITH AND JONES", or part of the generated value "A..B" becomes "fieldname between 'A' and 'B'".  Parsing SQL can be a slippery slope ...

I suspect you want to make the problem easier.  That is append the "*" during the CONSTRUCT as Seb suggested using the set and get field buffer methods.
http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_BuiltInFunctions_FGL_DIALOG_SETBUFFER.html
http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_BuiltInFunctions_FGL_DIALOG_GETBUFFER.html

What I will also throw into the mix is to use multi-dialog.   So for the field you are appending '*" to, that is in an INPUT, and you generate and append a string to the end of the where clause generated by the CONSTRUCT. 

Code
  1. DIALOG
  2.   INPUT BY NAME id
  3.   END INPUT
  4.   CONSTRUCT where_part BY NAME ON ...
  5.   END CONSTRUCT
  6. END DIALOG
  7. LET where_part = where_part, SFMT(" AND id MATCHES '*%1*'", id)

Or you have multi-dialog with a CONSTRUCT for each individual field.

Code
  1. DIALOG
  2.   CONSTRUCT BY NAME field1_sql ON field1
  3.   END CONSTRUCT
  4.   CONSTRUCT BY NAME field2_sql ON field2
  5.   END CONSTRUCT
  6.   ... etc...
  7. END DIALOG

then it is a case of manipulating the individual field SQL before concatenating back together.  This approach is good for adding UPPER() etc for case insensitive, or for doing OR instead of AND.

Reuben   

Product Consultant (Asia Pacific)
Developer Relations Manager (Worldwide)
Author of https://4js.com/ask-reuben
Contributor to https://github.com/FourjsGenero
ORGA-SOFT B.
Posts: 34


« Reply #5 on: May 23, 2018, 07:31:56 am »

Hello Reuben and Sebastien,

you have good ideas ;-).
We figured out a solution with the fgl_dialog_get and fgl_dialog_setbuffer.

Tanks for your good and fast support!

Perhabs we meet in munich next week.

Best regards
Martin Stigmond
Nuno G.
Posts: 14


« Reply #6 on: June 22, 2018, 07:05:48 pm »

MAIN
   DEFINE l_toBreak, l_delim STRING
   DEFINE l_tk base.stringTokenizer

   LET l_toBreak =
      "token 1 AND",
      "token 2 AND",
      "token 3 AND",
      "token 4 AND"

   LET l_delim = "AND"

   LET l_tk = base.stringTokenizer.createExt(l_toBreak, l_delim, "", FALSE)
   WHILE l_tk.hasMoreTokens()
      DISPLAY l_tk.nextToken()
   END WHILE

END MAIN


HIH
Sebastien F.
Four Js
Posts: 545


« Reply #7 on: June 23, 2018, 08:19:40 am »

Hello Nuno,

The delimiter parameter for the StringTokenizer create methods is not a word, it defines a set of single characters.

Passing "AND" means the delimiter can be "A", "N" or "D".

Try to replace:

Code
  1.   LET l_delim = "AND"

by:

Code
  1.   LET l_delim = "DNA"

See:

http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_ClassStringTokenizer_createExt.html

"The method can take a unique or multiple delimiters into account. A delimiter is always one character long."

Seb
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines