Julius Kavay · Nov 12, 2022 go to post

OK, no punctuation, no empty words, etc.... My lowest bid: 74 chars

ClassMethod Order(s)
{
	f  s p=$p(s," ",$i(i)),w=$tr(p,1/17),$p(z," ",$tr(p,w))=w ret:p=w$g(z)
}

By the way, the following three variants all have the same size of 74

	f  s p=$p(s," ",$i(i)),w=$tr(p,1/17),$p(z," ",$tr(p,w))=w ret:p=w$g(z)
	f{s p=$p(s," ",$i(i)),w=$tr(p,1/17),$p(z," ",$tr(p,w))=w ret:p=w$g(z)}
1s p=$p(s," ",$i(i)),w=$tr(p,1/17),$p(z," ",$tr(p,w))=wq:p=w$g(z) g 1
Julius Kavay · Nov 12, 2022 go to post

You say "No punctuation". OK, but then we have a contradiction: Example 4 of the test cases contains several commas, a dot and a question mark...

Julius Kavay · Nov 11, 2022 go to post

A small complaint:
- possible word delimiters weren't specified (space, tab, etc.)
- no specification about punctuation marks (allowed or disallowed)
- no specification about empty words (allowed or disallowed) and how to handle them, if allowed

So my question is, are the following examples legal or not:

"O2K. I'1m" --> "I'm OK."
"spac4es are2    1There     ma3ny" --> "There are many spaces."

Julius Kavay · Nov 10, 2022 go to post

Putting all in one line saves one byte

ClassMethod Order(sAs%String) As%String
{
	sd=" ",z="" f i=1:1:$l(s,d){s b=$p(s,d,i),c=$zstrip(b,"*n"),$p(z,d,$tr(b,c))=c} q z
}

Changing $zstrip() to a $tr() saves one more byte

ClassMethod Order(sAs%String) As%String
{
	sd=" ",z="" f i=1:1:$l(s,d){s b=$p(s,d,i),c=$tr(b,1E20/17),$p(z,d,$tr(b,c))=c} q z
}

So I end up with 86 bytes

Julius Kavay · Nov 9, 2022 go to post

and this is an updated version

ClassMethod Order(sas%String) As%String
{
	sd=" ",z="" f i=1:1:$l(s,d) s b=$p(s,d,i),c=$zstrip(b,"*n"),$p(z,d,$tr(b,c))=c
	q z
}
Julius Kavay · Nov 9, 2022 go to post

I do not work with Ensemble nor do I have Ensemble installed... But you could take a close look on that Ens_Enterprise_MsgBank.MessageHeader class, and check, if there is a mapping into an other, possibly readonly, database. Maybe somebody with ENS experience has a solution for you

Julius Kavay · Nov 9, 2022 go to post

As I learned the hard way, abstract classes do not have storage implementation, hence no indices either

Julius Kavay · Nov 9, 2022 go to post

One of the possible solutions

/// You can change the s:b]"" to an comma if there is always exact one space between the words/// and remove the ,1) from $lts() if all word are numbered from 1..N with no number missingClassMethod WordOrder(s)
{
    s z="" f i=1:1:$l(s," ") s b=$p(s," ",i) s:b]""$li(z,$zstrip(b,"*ap"))=$zstrip(b,"*n")
    q$lts(z," ",1)
}

This is a working solution and maybe not the shortest

Julius Kavay · Nov 8, 2022 go to post

I never had this kind of problem, but a quick and dirty method would be: 1) remove the 'Mount Read-only' flag, 2) run the tune table utility, 3) reenable the 'Mount Read-only flag'.  I hope, you do not have some mean application, waiting for the chance of his life, to get a writable database...

Julius Kavay · Nov 7, 2022 go to post

License counting depends on how you access Cache/IRIS (i.e. Web interface or some kind of client).

Julius Kavay · Nov 7, 2022 go to post

You can it enter via terminal, no question about, but it's a little bit cumbersome

// create the classs cls=##class(%Dictionary.ClassDefinition).%New()
s cls.ProcedureBlock=1s cls.Super="%RegisteredObject"s cls.Name="ObjectScript.RightTriangle"// add one methods mth=##class(%Dictionary.MethodDefinition).%New()
s mth.Name="Main"s mth.Description="Compute area and hypotenuse of a right triangle"d mth.Implementation.WriteLine($c(9)_"write !,""Compute the area and hypotenuse of a right triangle"",")
d mth.Implementation.Write($c(9,9)_"!,""given the lengths of its two sides.""")
d cls.Methods.Insert(mth)

// add one more methods mth=##class(%Dictionary.MethodDefinition).%New()
s mth.Name="Area",mth.Description="Area, computed from sides 'a' and 'b'"s mth.FormalSpec="a,b"d mth.Implementation.WriteLine($c(9)_"quit a*b/2")
d cls.Methods.Insert(mth)

// save the class (it's NOT compiled!)w cls.%Save()

As you may see, creating a class via an IDE is simpler... but yes, in an emergency case you can do it also via a console access

Julius Kavay · Nov 5, 2022 go to post

First, ##class(%PopulateUtils).StringMin(16,16)    generates random printable chars for testing (as replacement for user input) and is not ment to be used to generate cryptographic random chars. If you need cryptographic random chars, use $system.Encryption.GenCryptRand(length). This is just a hint and is not a reason for your current problem.

Second, despite my very limited C# experience, there is one thing in your code, I do not understand. If the initial vector (IV) is used, then it should be used (for enryption and decryption) the same IV on both sides, but you create an IV on Cache side (with the populate utils) and an other one on the C# side: byte[] IV = new byte[16]; (new Random()).NextBytes(IV);

That your decryption can't work.

To have a successful comunication, agree with the other party on
- a passphrase (the key), padding is done inside the encoding function 
- an IV (or left it empty on both sides)
- and on how the data will be sent:  either as the encoded (binary) data or as a readable (base64) data.ISC's implementation of AESCBCEncrtypt/Decrypt works well. One of my application uses it to communicate with an Windows application written in Delphi, without any problem since more the 15 years (we do not use the IV). So your problem will be some kind of a home-made problem:
- not using the same keys on both sides
- applying some kind of transformation (utf-8, base64, etc.)
- something suchlike

Julius Kavay · Nov 4, 2022 go to post

One of the problems could be the Bas64 encoding. This function inserts after each 76th byte a CRLF which possibly confuses the other party. Try with 

Set EncryptedBase64=$SYSTEM.Encryption.Base64Encode(encrypted, 1)

The parameter 1 says, do not insert CRLFs. Also, the text you encrypt must be an ANSI (8bit) text. If you are on a unicode system, you should call

Set encrypted=$SYSTEM.Encryption.AESCBCEncrypt($zcvt(text,"O","UTF8"),key,iv)
Julius Kavay · Nov 3, 2022 go to post

I understand your answer (#2) the way as this is a one time job. The simplest and quickest way to do this is:

- disable all indices (comment them out),
- compile the class or classes
- do the bulk insert
- enable all indices (by removing comment markers)
- compile the class or classes
- rebuild the indices

Class My.Class
{
    /*  disable all indices
    index1 someindex1 on someprop1;
    index2 someindex2 on someprop2;
    */
}
Julius Kavay · Nov 2, 2022 go to post

You are just one letter away from solution...

set db=##Class(SYS.Database).%OpenId("/trak/base/tc/db/ct",,.sc)
//................................^^^  Id, not ID!
Julius Kavay · Nov 2, 2022 go to post

The problem has nothing in common with Cache or IRIS, it's an OS setting. If a network drive is not available (for example the target is switched off), Windows waits an half an eternity.

You have to ask your sysadmin or Google, providing your Windows version. The very first hit I found is this but it's somewhat old.

Julius Kavay · Oct 20, 2022 go to post

Nice, merely your insert rate is somewhat low. About ten years ago, Cache inserted in proof-of-concept project  112000 rows per second. Seen in this way, the  (708000/20) 35400 are a bit little... 

Julius Kavay · Oct 20, 2022 go to post

I do not use Ensemble, but I would try using the JSON-Adaptor, something like this

Class MessageB Extends (Ens.Request, %JSON.Adaptor)
{
   Property ClientId As%String(MAXLEN = "");Property message As%Stream.TmpBinary;
}

For example

sr=##class(MessageB).%New()
sr.ClientId=12345dr.message.Write("part1")
dr.message.Write("part2")
wr.%JSONExportToStream(.s)
ds.Rewind()
ws.Read(s.Size) --> {"ClientId":"12345","message":"cGFydDFwYXJ0Mg=="}
Julius Kavay · Oct 20, 2022 go to post

REST-API is not my daily bread, so show me a few lines of your (problematic) code and I will try my best

Julius Kavay · Oct 19, 2022 go to post

Your solution is nearly perfect, here my quick (untested) version.

ClassMethod Encode()
{
	// You read N bytes (which MUST be divisible by 3) and write N*4/3 encoded bytes// 3 * 8190 = 24570; 24570 * 4 / 3 = 32760;  32760 < 32768; to avoid (slow) long stringsset CHUNK=24570set NOCR=1// don't insert CRLF after each 72 written bytesset encodedData=##class(%Stream.TmpBinary).%New() // adapt this to your needs: %Stream.Whatever...set request=##class(%Net.HttpRequest).%New()
	set request.Server="..."do request.Get("/...")
    
    if request.HttpResponse.StatusCode = 200 {
    	while 'request.HttpResponse.Data.AtEnd {
	    	do encodedData.Write($system.Encryption.Base64Encode(request.HttpResponse.Data.Read(CHUNK),1))
		}
	}
    QUIT encodedData
    
    // as an alternative, you could return a string or a streamobjectset YOURMAXSTRING = 32767// or 3641144if encodedData.Size <= YOURMAXSTRING {
	    do encodedData.Rewind()
	    quit encodedData.Read(encodedData.Size)
    } else { quit encodedData }
}
Julius Kavay · Oct 19, 2022 go to post

Assuming, fields which contains commas are quoted ("aaa,bbb,ccc") and (for the simplicity) fields does not contains quotes, then something like this should do the job

ClassMethod CSV(filename)
{
	s old=$system.Process.SetZEOF(1)	// use $zeof instead of error traps result=[]
	o filename:"r":0
	i $t {
		u filename
		while '$zeof {
			read line
			i line]""do result.%Push(..fields(line)) // ignore empty lines
		}
	}
	c filename
	d$system.Process.SetZEOF(old)
	q result
}

ClassMethod fields(line)
{
	s a="", f=0, row=[]
	f i=1:1:$l(line) {
		s c=$a(line,i)
		i c=44,'f d row.%Push(a) s a=""continue
		i c=34s f='f continues a=a_$c(c)
	}
	q row
}

A test output:


USER>s res=##class(DC.Help).CSV(fn)

USER>zso res
(0).(0).............: 12162
(0).(1).............: CHAPTER I
(0).(2).............: Certain infectious and parasitic diseases (A00-B99)
(0).(3).............: 003 (A20-A28)
(0).(4).............: Certain zoonotic bacterial diseases
(0).(5).............: A28
(0).(6).............: Other zoonotic bacterial diseases, not elsewhere classified
(0).(7).............: A28
(0).(8).............: Other zoonotic bacterial diseases, not elsewhere classified
(0).(9).............: N
(0).(10)............: N
(0).(11)............: N
(0).(12)............: N
(0).(13)............: N
(0).(14)............:
(0).(15)............:
(0).(16)............:
(0).(17)............:
(0).(18)............:
(0).(19)............:
(0).(20)............:
(0).(21)............:
(0).(22)............:

Julius Kavay · Oct 11, 2022 go to post

Oh yes, some 45 years ago, 2K (for caretaker and despooler), 4K as regular partition. Nowdays you need 2GB or 4GB! Just a factor of 10^6. And yes, I feel as a real developer too. The problems solution matters, not the tools.  

    

Julius Kavay · Oct 10, 2022 go to post

At least, you are one step further (in your initial post, you wrote "...because the code is hanging at Set tSc=Httprequest.Get(HttpURL)..."). Maybe the provided MAC number is wrong.  The MAC Number CC:1B:E0:E2:3C:10 belongs to Cassia Networks. Is that the right number?

I know exactly nothing about Cassia Networks and Cassia SDK... sorry.

Julius Kavay · Oct 10, 2022 go to post

This is just a hint: your Get() argument should be URL-encoded (colons are not allowed in an URL):

Set tSc=Httprequest.Get($zcvt(HttpURL,"O","URL"))
Julius Kavay · Oct 10, 2022 go to post

You are mixing two different things...

Property Data1 As list of %String;Property Data2 As%List;

are two very different things. The first (Data1, equates to your DataObj.Services) is an object while the second one (Data2) is a simple scalar value (in this case a string which in its structure casually matches the inner structure of a $list() respective $listbuild() function).

write$listvalid(oref.Data1) ==> 0// NOT a listwrite$listvalid(oref.Data2) ==> 1// a VALID listwrite$isobject(oref.Data1) ==> 1// a valid (list)objectwrite$isobject(oref.Data2) ==> 0// not a valid (list)object

$listnext() does NOT work on objects (your DataObj.Services) is an object

Julius Kavay · Oct 8, 2022 go to post

For a string like "hallo" Cache will use 5+2 = 7 bytes. If that "hallo..." is longer then 253 bytes then length_of_string + 4 bytes will be used and if your "hallo..." is longer then 65535 bytes then length_of_string + 6 bytes will be used.

But there is one more thing, you should know: the sum of the lengths of ALL properties, except the array(like) properties, can't be greater then that famous 3641144 magic number (if you use the standard Cache Storage). Array-like properties are those, which are stored in own nodes.

Julius Kavay · Oct 6, 2022 go to post

Use this link as a starting point and consider using either $FIND() or $LOCATE() to narrow down the string you're looking for and then use $EXTRACT() to extract the href value. By the way, it's enough a short example string, posting nearly the whole page is an overkill and wasting space.

Julius Kavay · Sep 30, 2022 go to post

Hence I wrote to OP, quote from my answer, "you ask WRC for a 'WriteStream()' method" 

Julius Kavay · Sep 30, 2022 go to post

According to WebSocket protocol, the maximum payload size is (2**(8*8))-1 octets, if I recall it right.