Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

call FileMaker-Scripts #41

Open
chmich opened this issue Mar 31, 2018 · 3 comments
Open

call FileMaker-Scripts #41

chmich opened this issue Mar 31, 2018 · 3 comments

Comments

@chmich
Copy link

chmich commented Mar 31, 2018

Dear, makers of this really smart gem!

Could it be possible to implement a new feature?

Altough your gem is made to deal with records, it could be the a fine tool to call FileMaker-Scripts on the FileMaker-Server and get the results back?
I know, like many things in FileMaker, this would be a fairish hack, but a great help for many cases.

Situation:
In near Future, it may be that with the restFM-Interface, the dealing with Scripts would become easier, but there are a lot of older versions running and there are reasons to maintain a older Version and don't update.
Examples: In File-Maker its common to rename Fields. If you have a big system with a lot fo xml-Interfaces and a 100% FileMaker-Developer in the team or the chief of the company also develops in the System, you can tell them 100 times that it's not allowed to rename Fields - you will have a problem.
If you want to push larger texts to a older FileMaker, it can not receive by 'put', so it blocks. You have to call a FileMaker-Script, which gets it by 'get'.
This are only two examples - there are more reasons.

To call a FileMaker-Script over the XML - Interface, you have to call a layout, and then you can call a script see: XML-Interface (url: "..&-script="). This is the easier part.
More complex is to deliver back the result over the xml-interface:
You have to call the Script by ".prefind", then give a UID with the parameter, the FileMaker-Script does his work, creates a record with this uid and the result, and in the same step, the XML - Interface finds and picks up this record and delivers it back within the xml - result. Yes, sorry, this is a real Hack!! But, this steps could be implemented once in this gem and given a description or a example for the FileMaker-Side. I've written such a logic in Xojo for interacting with FileMaker and it works very stable and also on the older FileMaker-versions.
If this FileMaker-Script runs with full privileges, it is then able to do anything on the FileMaker-Side, also on other layouts and Tables.

Problem: give Script-Parameters to FileMaker
In the XML - interface, FileMaker can only receive a single Script-Parameter in one string.
Since FileMaker-16, fileMaker can deal with json. To have Json-Ability on older Versions you can install Base-Elements on FileMaker-Server. A other way to give FileMaker multiple Script-Parameters is to deal with Custom-Functions. One Example, i've written, i've attached.

If you or we can implement this new Feature to this gem, i could deliver the counterpart as a example-FileMaker-File and we could deliver this with your gem.

Many thanks and best Regards in advance,
chmich

SetPar_Demo.fmp12.zip

@chmich
Copy link
Author

chmich commented Mar 31, 2018

UPDATE
now i've made my own soulution.
it works very stable and handles all exeptions (Connection to FileMaker and FileMaker-Script-Errors)
may it help someone.


config/filemaker.yml

domain: xxx

timelog_scan:
    username: xxx
    password: xxx
    file: xxx
    layout: "xx

class Fmscript

  def timelog_scan( script, parameter )
    run( "timelog_scan", script, parameter, ["parse-json"] )
  end

  private

  def run (model, script, parameter, options)


    config = YAML.load(File.read('config/filemaker.yml'))


    auth = {:username => config[model]['username'], :password => config[model]['password']}
    base_url = "https://#{config['domain']}/"
    result_key = SecureRandom.hex(5)
    param = "$result_key=#{result_key}#{parameter}"
    url = "#{base_url}fmi/xml/fmresultset.xml?-db=#{config[model]['file']}&-lay=#{config[model]['layout']}&-script.prefind=#{script}&-script.prefind.param=#{param}&result_key=#{result_key}&result_key.op=eq&-find"


    result = HTTParty.get(url, :basic_auth => auth) rescue "rescue-error"


    res = {}
    res['message'] = ( result == 'rescue-error' ? "ERROR: FileMaker not available ()" : "ERROR (could not connect to FileMaker)")
    res['fm_errorcode'] = "?"
    res['fm_foundresults'] = "?"
    res['result'] = ""

    a = (result.to_s[0..4] == "<?xml")
    b = (result.to_s.last(26) == "</resultset></fmresultset>")

    if a != true or b != true
      Log.create(:title => "ERROR", :description => "could not connect to FileMaker-Script", :details => ":url => #{url}")
    else
      res['fm_errorcode'] = result.parsed_response['fmresultset']['error']['code']
      res['fm_foundresults'] = result.parsed_response['fmresultset']['resultset']['count']
      if (res['fm_errorcode'].to_i != 0 or res['fm_foundresults'].to_i != 1)
        res['message'] = "ERROR (FileMaker-Error: #{res['fm_errorcode']} found-Results: #{res['fm_foundresults']})"
        Log.create(:title => "ERROR", :description => "FileMaker-Script-Error: #{res['fm_errorcode']} found-Results: #{res['fm_foundresults']}", :details => ":url => #{url} :XML-result => #{result}")
      else
        # SUCCESS
        res['message'] = "SUCCESS"
        block_1 = result.to_s.split("<field name=\"result\">")[1]
        block_2 = block_1.split("</field>")[0]
        block_3 = block_2.split("<data>")[1]
        res['result'] = block_3.split("</data>")[0]
        res['result'] = URI.decode(res['result']) if options.grep(/url-decode/).count >= 1
        if options.kind_of?(Array)
          if options.grep(/parse-json/).count >= 1
            # If result is a valid JSON => return parsed JSON
            js = JSON.parse(res['result'])
            if js.present?
              res['result'] = js
            end
          end
        end
      end
    end

    return res
  end

end

@ginjo
Copy link
Owner

ginjo commented Jul 19, 2018

Hey @chmich , sorry I missed this post,

I'm not sure if I fully understand the problem you're trying to solve. Is it an issue with Rfm's implementation or with a missing functionality of Filemaker's XML interface? Or maybe both?

Version 4 of RFM will have some significant changes. Most notably, it splits the query code, the xml parsing, and the data modeling into separate modules (or likely separate gems). This should make it more flexible and more sustainable into the future. It should also make it simpler to set-up, configure, and make calls to FM Server. I imagine a REST API implementation would just be another module in the new Rfm "suite".

However... I can't tell yet if the REST/JSON API is a viable replacement for the XML interface. Without the metadata in the JSON response, Rfm would not be able to translate data types between Filemaker and Ruby. They did add perform-script in FM Server 17, but I haven't experimented with it yet. Looks like it has the same requirements as the XML API (including a layout name).

@chmich
Copy link
Author

chmich commented Jul 19, 2018

Hi ginjo, thanks for your reply!
my "problem" is solved, it's the method above 'class FmScript', and it works fine.
The idea was to implement this in your gem, to have configutations on one place.

Situation is:
FileMaker-17 implemented Features that does more or less what we need, but very probably they will add a licence on this interface in the future. They told this up from beginning and they already added a Data-Counter in the Interface.

  • "Freezing" of Field-Names in FileMaker => in all other languages nobody will change fieldnames, but in FileMaker this practice is very common.
  • Perform FileMaker-scripts, pass parameters and receive the result

By reading and writing records, from rails by FileMaker-Script you have no problem if a FileMaker-developer changes a filed-name. In XML, you have a problem. Its more work for the developer on this way, but then its stable.

For the case, you are interested to implement this feature in your gem, i updated my above script to my current version.

Best Regards,
Christian

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants