Eduard Lebedyuk · Jun 12, 2018 go to post

Unrelated but it's better to return a status from a generator method:

ClassMethod GenerateMethods() As %Status [ CodeMode = objectgenerator ]
{
    For i=1:1:%class.Methods.Count() {
        #dim method As %Dictionary.MethodDefinition = %class.Methods.GetAt(i)
        Continue:((method.Description["@AutoGenerated") || (method.CodeMode="objectgenerator"))
        Do %class.Methods.Insert(##class(util.TestGenerator).Generate(method.Name_"DoSomethingElse",%class.Name))
    }
    Quit %class.%Save()
}
Eduard Lebedyuk · Jun 12, 2018 go to post

What flags are you compiling with? For me it works on a first compilation:

USER>do $system.OBJ.UnCompile("util.*")
 
Uncompiling class util.Test
Uncompiling class util.TestGenerator
USER>do ##class(util.Test).TestOneDoSomethingElse()
 
DO ##CLASS(util.Test).TestOneDoSomethingElse()
^
<CLASS DOES NOT EXIST> *util.Test
USER>do ##class(util.TestGenerator).Generate()
 
DO ##CLASS(util.TestGenerator).Generate()
^
<CLASS DOES NOT EXIST> *util.TestGenerator
USER>do $system.OBJ.Compile("util.*")
 
Compilation started on 06/12/2018 20:13:00 with qualifiers ''
Compiling 2 classes, using 2 worker jobs
Compiling class util.TestGenerator
Compiling routine util.TestGenerator.1
Compiling class util.Test
Compiling routine util.Test.1
Compilation finished successfully in 0.012s.
 
USER>do ##class(util.Test).TestOneDoSomethingElse()
util.Test||TestOneDoSomethingElse

As you see from the log both classes don't exist, but after one compilation I can call TestOneDoSomethingElse method and it works. What's your output for:

do $system.OBJ.UnCompile("util.*")
do ##class(util.Test).TestOneDoSomethingElse()
do ##class(util.TestGenerator).Generate()
do $system.OBJ.Compile("util.*")
do ##class(util.Test).TestOneDoSomethingElse()
Eduard Lebedyuk · Jun 12, 2018 go to post

I tried method generators, but It only gets compiled when I compile for the second time.

Please show a sample. Compiling a class with method generators should work on a first compilation.

Eduard Lebedyuk · Jun 11, 2018 go to post

What's the purpose of a normal index over a text field? I assume user searches by a substring. There are two and a half ways to perform a fulltext search:

  1. Define a property of %Text type and use language class. New language classes an be added fairly easily. Documentation. Removed in InterSystems IRIS and therefore not recommended.
  2. Use iFind indices. They  are highly customisable.
  3. Use iFind indices creatively. You can build your own indices based on iFind indices and you can write your own tokenizers, etc. Also it's possible to define your own custom index. Community article on that.
Eduard Lebedyuk · Jun 9, 2018 go to post

Yes. I set use locale defaults  to true and rebuilt the cube. After that Analyzer started showing localized date values.

Eduard Lebedyuk · Jun 9, 2018 go to post

What do you mean? How does it look in config file?

In the best case like this:

{
  "storage-driver": "devicemapper",
  "storage-opts": [
    "dm.directlvm_device=/dev/xdf",
    "dm.thinp_percent=95",
    "dm.thinp_metapercent=1",
    "dm.thinp_autoextend_threshold=80",
    "dm.thinp_autoextend_percent=20",
    "dm.directlvm_device_force=false"
  ]
}

Docker documentation explains setting direct-lvm in detail.

Eduard Lebedyuk · Jun 9, 2018 go to post

There are system implementations too:

>write $$toRoman^%bi.SWr.FolderTest(124)
CXXIV
>write $$toRoman^%bi.SWr.FolderTest(1245)
MCCXLV
Eduard Lebedyuk · Jun 9, 2018 go to post

If you're sure that all your keys are consecutive integers, then use $order to get the last element, which would also be a count of them:

write $order(a(""),-1)
Eduard Lebedyuk · Jun 7, 2018 go to post

If you  want to connect to external database, couldn't you just provide domain name and password and authenticate with that?

Eduard Lebedyuk · Jun 7, 2018 go to post

KILLdes is a record for kill of descendents journaled as part of a higher-level kill inside of transaction.
So it's a Kill command.

Eduard Lebedyuk · Jun 7, 2018 go to post

%DeepSee.Utils:%FormatDate offers this options

Format a date value (in $H format) according to the format in pFormat. The format string can contain:

  • "y" - Year number (4 digits).
  • "q" - Quarter number.
  • "m" - Month number, with no leading zero.
  • "mm" - Month number, with leading zero.
  • "mmm" - Short name of month (using server locale).
  • "mmmm" - Long name of month (using server locale).
  • "d" - Day number, with no leading zero.
  • "dd" - Day number, with leading zero.
  • "ddd" - Short name of day (using server locale).
  • "dddd" - Long name of day (using server locale).
  • "\x" - display character "x"
  • " " - space
  • "/" - "/"
  • "-" - "-"
  • "." - "."

Added mm as Time Format and rebuilt cube. Got 01 instead of JAN.

Removed mm. Turns out, all you need to do is to use locale defaults in Locale Settings

Eduard Lebedyuk · Jun 7, 2018 go to post

Not that Count approach is while easiest, can significantly slower the query down.

Extending the adapter so you have an "after all rows" callback has speed advantage and also you wouldn't need to rewrite your queries to add Count().

Eduard Lebedyuk · Jun 6, 2018 go to post

Follow these steps:

  1. Change superclass from %Persistent to %RegisteredObject
  2. Delete Storage part of class definition.
  3. Compile.

Table should be gone after that.

If you already deleted the class in Atelier (and synced that change with a server) the the table would be gone too.

Eduard Lebedyuk · Jun 6, 2018 go to post

Use Send method:

Set httprequest = ##class(%Net.HttpRequest).%New()
Set httprequest.Server = "www.intersystems.com"
Set sc = httprequest.Send("PATCH", location, test, reset)
Eduard Lebedyuk · Jun 6, 2018 go to post

Do you wan to do something specific with the last row or do you just want a callback after all rows?

If it's the later, you can subclass SQL inbound adapter:

Class Project.Ens.Adapter.SQLInbound Extends EnsLib.SQL.InboundAdapter {

Method OnTask() As %Status
{
  Set sc = ##super()
  // all rows were just processed
  // add your logic here
  Quit sc

}

}

Other approach is to UNION a dummy row to the end of your query, or add COUNT() property.

Eduard Lebedyuk · Jun 5, 2018 go to post

Like this?

 write $case(condition,
             1:"hello " _
               "world",
             2:"name",
             :"!")

Hello world is a multiline expression.

Eduard Lebedyuk · Jun 5, 2018 go to post

I'd go with if, but you can also resolve case expression beforehand:

set condition = .... several lines of logic...
write $case(condition, ...)

And condition then can be separaten into several different lines.

I'm against method chaining in general and several functions on one line/step in particular.

Each line should contain one small operation.