Question Jenna Makin · Sep 29, 2017

Are Config.* classes backwards compatible to previous versions of the cpf format?

Hi-

I am running the latest version of Cache and am trying to use the Config.* classes in the %SYS namespace to be able to gather information from a cache.cpf file that was provided to me by a customer.  The customer is running an older version of Cache which had a different Version number in the cpf file.  Theirs is 2013.1 and mine is 2015.1.  

My question is, are the Config.* classes backwards compatible.  Can I use a 2017.1 version of Cache to read information from cpf file from a 2014 system?

Comments

John Murray · Sep 29, 2017

Interesting question. What have your attempts shown so far?

0
Eduard Lebedyuk  Sep 29, 2017 to Robert Cemper

Prepare doesn't require arguments, only execute does.

You can prepare query once and then execute it several times with different arguments.

0
Jenna Makin · Sep 29, 2017

I was able to use the Config.Namespaces (Exists) method to determine if a given namespace was defined and also to gather attributes for it.
I am attempting to use the List query of the Config.MapGlobals class to gather global mappings for the namespace and it's not returning anything.  

0
John Murray  Sep 29, 2017 to Jenna Makin

Presumably you've verified that your code for doing that does work as expected when it's processing your instance's own CPF?

0
Jenna Makin · Sep 29, 2017

Interestingly I just tried to use the List query to gather global mappings for a namespace in the active configuration and it didnt return anything..

%SYS>s rs=##class(%ResultSet).%New("Config.MapGlobals:List")

%SYS>s sc=rs.Prepare("HSEDGEREST","*")

%SYS>w sc

1

%SYS>w rs.Next()

0

%SYS>

Am I doing something not quite right here?

0
John Murray  Sep 29, 2017 to Jenna Makin

Prepare() is for dynamic SQL, but in your case it's a class query you want to run. So change your rs.Prepare call to be an rs.Execute one.

Or use the following as a quick verification:

%SYS>d ##class(%ResultSet).RunQuery("Config.MapGlobals","List","HSEDGEREST","*")

0
Jenna Makin  Sep 29, 2017 to John Murray

Thanks John-  This was exactly my problem.  

0
Robert Cemper · Sep 29, 2017

Hi Ken,

For some odd reason Execute() requires he same parameters as Prepare() again !


%SYS>set rs=##class(%ResultSet).%New("Config.MapGlobals:List")
%SYS>write rs.Prepare("ENSDEMO","*")
1
%SYS>write rs.Execute("ENSDEMO","*")
1
%SYS>write rs.Next()
1
%SYS>.....
 
      Just hacking around.
0
Robert Cemper  Sep 29, 2017 to Eduard Lebedyuk

as the class  is deployed YOU may have access to the sources.

0
Eduard Lebedyuk  Sep 29, 2017 to Robert Cemper

It's in the docs:

The query may contain parameters represented by ? characters within the query. The values of any parameters are supplied via the Execute method.

0
Robert Cemper  Sep 29, 2017 to Eduard Lebedyuk

That's fine and nothing new.
You missed my point:

With the Class Query it's not self explaining if params got to Prepare() or to Execute()
http://docs.intersystems.com/latest/csp/documatic/%25CSP.Documatic.cls?…

I just learned from  John Murray a few comments above

Prepare() is for dynamic SQL, but in your case it's a class query you want to run.
So change your rs.Prepare call to be an rs.Execute one.


that you don't need a prepare with a Class Query.
I wasn't aware of that until a few hours ago.
Then it's obvious that any param has to go to Execute().

0
Eduard Lebedyuk  Sep 30, 2017 to Robert Cemper

If you want to execute a class query and get a result set you can directly call <Query>Func method and get a new %SQL result set:

set rs = ##class(Config.MapGlobals).ListFunc("ENSDEMO","*")
while rs.%Next() {
  w rs.Name,!
}

The only case where you can't use that if you need to choose the query at runtime.

0