Warlin Garcia · Oct 17, 2016 go to post

Relationships load a "collection" of pointers to the members of the relationship. Objects are loaded to memory only when accessed. Pretty much how Arrays work as well. In essence Arrays and Relationships work the same. Relationships provide the extra referential integrity.

Warlin Garcia · Jun 7, 2017 go to post

Can you elaborate on this: "For performance reasons we suggest using Foreign Keys instead of relationships."

My understanding is that Relationships will create the foreign keys (and the relationship table) for you similar as you would do in the relational world:

TableA

AID

TableB

BID

TableABRelationship

AID

BID

FK: AID

FK: BID

Warlin Garcia · Jun 13, 2017 go to post

You can manage without. You have plenty of Object Oriented options to get to the items.  Or you could use $O over the global to get the IDs (similar to what Extent would do)

Warlin Garcia · Jun 13, 2017 go to post

$ORDER would do. Not the cleanest (or preferred) but the point being you can do without SQL.

Warlin Garcia · Jun 13, 2017 go to post

Cache doesn't provide this "out of the box" but you can always create a class that works as a Collection (a collection of IDs if you will) and provides an Iterator interface/functionality for to you iterate over the values.  You can always expose and access data through Objects as you need to.

Warlin Garcia · Jun 22, 2017 go to post

Can you provide more details on what exactly you're trying to accomplish? As you said, the last query works. What exactly is missing? Are you trying to get a prompt (outside of Cache I'm guessing) with the parameter name?

Warlin Garcia · Jul 19, 2017 go to post

The only "caution" here is that referencing the property by name only works with properties where the SqlFieldName corresponds to a valid Cache property name:

  1. Property myproperty As %String;
  2. Property myproperty As %String [SqlFieldName = "mysqlname"];
  3. Property myproperty As %String [SqlFieldName="my_property"];

You can access #1 & #2 by property name, however #3 you can only access by using %Get("my_property");

Warlin Garcia · Jul 19, 2017 go to post

Can you add more information as what is the exact problem you're facing?

If you're accessing the database through ODBC you can craft the query with any name you need to. With that said, your option of having a variable with the name + a date should work as long as this variable is within your application (client). 

If what you want is for the database to handle the variable and the logic to assemble the table name then you need to go with a stored procedure as mentioned by Eduard.

Warlin Garcia · Jan 11, 2018 go to post

Can we infer form this that sharding can be applied to globals that have been mapped to classes (thus providing SQL access)?

Warlin Garcia · Jan 12, 2018 go to post

Alex, it's all based on your design. The decision of whether a method is an instance or class method is totally independent of whether that method can be private or not. Your design, and patterns or best practices you want to follow, will dictate which way to go. The benefits are in what you want to accomplish with the design: ease of testing, ease of change, etc. 

Warlin Garcia · Jan 12, 2018 go to post

Let's say I have an orders global with the following structure:

^ORD(<ID>)=customerId~locationId.....

And I create a mapping class for this global: MyPackage.Order

Can I use sharding over this table?

Warlin Garcia · Jan 12, 2018 go to post

I understand the accessing part but by creating a class mapping I'm enabling SQL access to the existing global. I guess that the question is more in line on whether sharding will be able to properly partition (shard) SQL tables that are the result of global mapping? Are there any constraints on how the %Persistent class (and the storage) is defined in order for it to work with sharding? Should they all use %CacheStorage or can they use %CacheSQLStorage (as with mappings)? 

Warlin Garcia · Jan 24, 2018 go to post

Agree with brace always. This really helps with new developers as the syntax is something they've seen before in other languages. 

Warlin Garcia · Jan 25, 2018 go to post

If you want to check on the result of a LOCK command for example 

LOCK +<SOMERESOURCE>:<timeout>

IF $T {do something}

So I wouldn't call it bad practice just yet.

Warlin Garcia · Apr 30, 2018 go to post

These are compiler instructions. Not sure if the instructions change based on the cache installation language (e.g. English vs. Portuguese). You can change the language for Studio based on your locale but that's only for menus and such.

Warlin Garcia · May 7, 2018 go to post

Do you mind sharing what are you trying to accomplish that you need a dynamic table creating mechanism?

Warlin Garcia · May 11, 2018 go to post

There's certainly a performance gap. The significance depends on what you're trying to do. For most jobs it'll be very very insignificant.  In general SQL is a little bit faster than Object access, however Object access provides other benefits in terms of code clarity and reusability. In the case of interacting with Cache from other languages (e.g Java/Spring) then SQL will be preferred for lots of reasons. The main one being that SQL, as Robert Cemper said, it's a well supported and known language. 

Warlin Garcia · May 30, 2018 go to post

For large files I use %XML.TextReader.ParseFile(). It allows me to pass a "concrete" global instead of using Cache defaults. Usually CacheTemp which is more limited than a concrete global. With this I'm able to process larger files. Granted, it's a little bit of more work (code) as you have to traverse the results (element by element) but it gets the job done.

Warlin Garcia · May 30, 2018 go to post

Understand. I haven't tried this myself yet but in theory you should be able to initialize the Reader with an XML.Document object. This Document can be initialized (%OnNew) with a global of your choice in the same manner that TextReader can. 

Warlin Garcia · May 30, 2018 go to post

Correct. The alternative using TextReader was to "avoid" increasing memory but if you have that option then the answers provided by Timothy are the way to go.

Warlin Garcia · Jul 2, 2018 go to post

Code placement depends on what you're trying to do and when: if processing the event from javascript (ajax call) then your code must be separate from OnPreHTTP(); if processing on the server (after page submit) then your code should be in OnPreHTTP() or called from it (this last part depends on your coding style - jam everything in a single method or separate things in multiple smaller methods)

In simple terms (as Robert pointed out) , OnPreHTTP needs to handle any processing the server must perform prior to "displaying"/"printing" the page on the browser.

Warlin Garcia · Aug 13, 2018 go to post

Is ClassDefinition available even if you deploy without the source code e.g. OBJ version?

Warlin Garcia · Aug 14, 2018 go to post

Agree on your "usefulness" statement. Making a class non-extendable breaks all recommended development practices. For example TDD. I won't be able to mock this class for testing purposes and will be forced to test with your class only (Granted Cache is not strong typed so in theory I have ways to bypass this limitation but still). 

Another recommended principal is to use composition instead of inheritance so in theory I could do exactly the same I wanted to do with your class (after you "lock it down") by making it part of another class without extending it. If a developer wants to get around your class ( don't know the reasons why) he/she can by other means unless you plague your code with a bunch of type checks (making Cache strong typed). 

Even if a developer get to extending your class, the fact you can't overload methods in Cache gives you a level of restriction when combined with deployed code and final as there's "no way" a developer can change your implementation so your code will still call your methods' implementation on a subclass.

All and all it seems you're going to extremes for no real benefit but since we don't know the whole picture maybe this effort is worth it. 

Warlin Garcia · Aug 17, 2018 go to post

Besides dynamically changing the maxlen what else are you trying to accomplish/avoid? These values are used at compile time to generate the SQL catalog and become part of your contract (for clients calling them). If you were to dynamically change the values 1) you'll be breaking the contract (e.g. you could change the values to a more restrictive size) and 2) you would still need to compile the class holding the stored proc/query. 

The benefit I can think of this approach right now is avoiding pushing code to prod (assuming that process is cumbersome), however you still need the compile part.  It'll be better to define and modify the stored proc using DDLs (maybe  a faster change in prod depending your company's rules).  Since this change is a database object change it should be treated as code and thus (hopefully) kept in source control (for audit and replication purposes). 

Warlin Garcia · Sep 20, 2018 go to post

Even SQL operations are captured in the journals as far as my understanding goes. But I'd agree any solution would have to check on any scenarios such as data not being journaled since processes can disable journaling "at will".  Journaling can also be disabled at the db level.

Going under the assumption that "everything" is captured in the journals it should be possible to write a process that reads the journal file and convert its entries to another format.

Warlin Garcia · Oct 25, 2018 go to post

I'm not sure there's a Cache specific document for designs like this. There are multiple ways to separate data in any database (schema, instance, namespaces, etc). Cache provides extra features such as namespace mappings that makes sharing simpler but before you get to Cache specific implementation you need a high level design of your application. Regardless of database and programming language, how should my application work?  How do you plan to sell your product? How flexible you want it to be? As Dmitry pointed out, are there any regulations/limitations around sharing data within customers? All this should be based on your  business model and has nothing to do with technology stack. 

Warlin Garcia · Jan 30, 2019 go to post

Can you provide what you get from this command set sc=res.Prepare(sql,,conn)? The error should tell you why the query failed preparation.