In the first two parts of this series we had gotten to the point where we could search the Bible for a set of words with a couple of simple lines of ECL. The challenge for part III was "what did we need to do to make a service to do the same thing that could be invoked by SOAP or from the Web?" Look at the following code:
It should look vaguely familiar; it is almost identical to the code we executed in part II to test out our search capability from within the IDE. However, if you follow the steps in the tutorial on the HPCC Website (which essentially tell you to Compile the code and the select Publish from the ECL Watch screen) - this is all you need to do to make your Bible search callable from a SOAP call or from an HTML page.
Which should produce:
So, what was the extra piece of magic to turn our ECL Query into a soap callable query? It was the line with the STORED declaration. A STORED declaration tells the system that it is going to use a WorkUnit value. Many people confuse WU values with Global Variables. They are not; they are values provided at the start of a job by an external source and which are then constants for the lifetime of the job. In this particular instance the Publishing of a compiled WorkUnit with STORED values tells the ECL system that an input mechanism (SOAP Interface) to provide that stored value is required; the rest is automatic.
Technically we have already done all that we claimed we would do for part III; but that was so easy I want to use the rest of the article to tidy up the output a little. Rather than have the reference as separate Columns I would like to construct some nice clean text for the reference.
The problem falls into two fairly small pieces; firstly we have to convert the BookNum back to a book label and then we just need to format things into one column. If there were lots of books, or if the list was dynamic, I could use an index to map from booknums to text. However, given there is a short list that has been fairly static for over 1700 years I think we can risk burning the mapping into code. This can be done by typing but my article MAC_BuildCase shows you a programmatic way to create the code.
With that function I can now perform all the mapping I need using a TABLE statement:
Note that the previous output (the .GetBatch) has now been made an attribute which is passed through a TABLE statement which handles all of the formatting. The word 'Verse' is the label of the text but will also appear as the column heading for the result. Therefore if you publish the Roxie service as before - the results will look like:
Of course this is still far from a professional website; the HTML response is really for quick development and internal use. If you want to go professional and fancy you will need to call your Roxie service (which is a SOAP service) using SOAP. Fortunately the Links tab of WS-ECL (which is just behind the form you were entering data into) contains a list of links to help develop and debug your newly created SOAP service.
Well, I am going to claim that I have now delivered on the original promise; we have a passable search capability from scratch data delivered through Roxie. We can't do sophisticated searching; that might come later. Next however I want to start exploring some of the value that can be derived by actually analyzing the text using math. This is not going to be some kind of 'Bible Code' exploration; rather it is going to be looking to find some statistics to find the linkages and cross references that the Bible contains.
The whole query in cut & paste able form is here:
import kjv,std.Str as *; STRING ToSearch := '' : STORED('SearchText'); s := KJV.Inversion.Search(ToSearch); IntToBook(INTEGER i) := CASE(i,1 => 'Ge',2 => 'Ex',3 => 'Le',4 => 'Nu',5 => 'De',6 => 'Jos', 7 => 'Jg',8 => 'Ru',9 => '1Sa',10 => '2Sa',11 => '1Ki',12 => '2Ki', 13 => '1Ch',14 => '2Ch',15 => 'Ezr',16 => 'Ne',17 => 'Es',18 => 'Job', 19 => 'Ps',20 => 'Pr',21 => 'Ec',22 => 'Song',23 => 'Isa',24 => 'Jer', 25 => 'La',26 => 'Eze',27 => 'Da',28 => 'Ho',29 => 'Joe',30 => 'Am', 31 => 'Ob',32 => 'Jon',33 => 'Mic',34 => 'Na',35 => 'Hab',36 => 'Zep', 37 => 'Hag',38 => 'Zec',39 => 'Mal',40 => 'Mt',41 => 'Mr',42 => 'Lu', 43 => 'Joh',44 => 'Ac',45 => 'Ro',46 => '1Co',47 => '2Co',48 => 'Ga', 49 => 'Eph',50 => 'Php',51 => 'Col',52 => '1Th',53 => '2Th',54 => '1Ti', 55 => '2Ti',56 => 'Tit',57 => 'Phm',58 => 'Heb',59 => 'Jas',60 => '1Pe', 61 => '2Pe',62 => '1Jo',63 => '2Jo',64 => '3Jo',65 => 'Jude',66 => 'Re','?'); res := KJV.File_KJV.GetBatch(s); r := RECORD STRING Verse := IntToBook(res.BookNum) + (STRING)res.Chapter + ':' + (STRING)res.Verse + ' ' + res.Verse_Text; END; TABLE(res,r)