Re: Set_Exists() function: Simple version

2017-07-16 Thread David Adams via 4D_Tech
Justin's interpretations of my email are correct. For the record, here's
the error handler:

Error:=Error

So, yeah, nothing exciting there.

I posted my code because I'm not confidant in it. I don't remember when I
wrote it and I haven't kept up with all of the various permutations on
where sets are stored, etc. Some server, some local, etc. No clue. (I asked
about how this is meant to work in pre-emptive processes because my results
surprised me, but I never did hear back that I can recall.)

So, I'd be grateful if anyone that is Really Into Sets (we all know you're
out there!) gave it some thought. If it's reliable, great! If not, I'll
kill it rather than rely on it.

I'm with Justin on the IP flag in the error handler. That's provably
unreliable in a multi-process system.

Thanks for all comments and help!
**
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**

Re: Thinking through object/text fields: Findings summarized, advice solicited

2017-07-16 Thread David Adams via 4D_Tech
> On Mon, Jul 17, 2017 at 6:50 AM, Julio Carneiro via 4D_Tech <
4d_tech@lists.4d.com> wrote:
> Correct, David, you got the gist of my comment.

> Jim Hays gave a great example where I can see object fields excel. If
your app
> requires user defined fields, then an object field is just perfect for
that.
> I’ve had similar situations in the past and used tab-separated text fields
> first, and then blob fields when that became available. Now object fields
> would be much much better because you can query on those ‘user defined’
> fields, a great improvement over previous implementations.

Yes, I can easily see that object fields are the best current, native way
to handle user defined fields in 4D. I'm getting the impression that is
pretty much their entire purpose, or close to it. I can see how that is
value to some OEMs (I'd expect DataWorks to use it as they've always found
UDFs a competitive advantage for them.) But for me? I've never had that
requirement and don't expect to.

The uses I have for storing JSON sound like they're just not on the list of
problems that object fields in 4D are *intended* to solve. So, it's not a
great match. I had a quick look at what PostgreSQL offers and their 9.4
release (2.5+ years ago) has a couple of native options. They've got a
'json' field type and a 'jsonb' field type. The first is for straight
validation of JSON as it is, but with engine-level validation. So,
basically a text field that can store any valid JSON that kicks an error if
you put something else in. The jsonb type restructures the JSON into a
custom binary format for index optimization. Not to save space, but to make
searches possible, flexible, and fast. This is integrated with some ongoing
work they've been going with full-text searching, a la Solr. (The GIN
index, specifically.) So, super optimized to complete for a lot of the
spaces that MongoDB plays in. PostgreSQL supports some syntactic
conventions to allow for indexed searches *within* nested JSON, very nice.

Out in that wider world, saving raw JSON for log analysis, messaging, API
analysis, pre-calculations, etc. is all entirely ordinary. In an all 4D
world, apparently not so much. In an all 4D world, those uses seem to be
"not recommended." In a world where 4D is part of a larger pipeline, some
of the other tools sound like a more natural fit for JSON storage.

It took me about 45 minutes to get a really good sense of the options in
PostgreSQL along with costs, limitations, trade-offs, and competitive
comparisons. The information was available at whatever level of technical
detail I could have been interested in...and then some. It's pretty fun to
read about this stuff.
**
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**

Re: Set_Exists() function: Simple version

2017-07-16 Thread Justin Carr via 4D_Tech
On 17 Jul 2017, at 5:07 am, Robert Livingston via 4D_Tech 
<4d_tech@lists.4d.com> wrote:
> 
> On Jul 14, 2017, at 5:10 PM, David Adams via 4D_Tech <4d_tech@lists.4d.com> 
> wrote:
>> 
>> I was just consolidating some old code and ran across something that I
>> wrote some time back called Set_Exists. No clue. It seems to work, but I
>> can't say why.
> 
> No clue??  I cannot say why?? I am not sure whether this is a joke that I 
> don't get or what.
> 
> It would seem to be fairly clear that the basic logic here is to use the 
> 
> Is in set()Command to test for whether a set exists. The documentation 
> says that if a set does not exist, then this will throw an error. So the code 
> is taking advantage of this

Hi Robert

Are you able to provide a link to where the documentation states this?

> Then he asks us to confirm if the code is reliable. But there are three 
> methods included in the code
> 
> ErrorHandler_Install
> ErrorHandler_SuppressError
> ErrorHandler_InstallPrevious
> 
> that we are not given. How am I supposed to test it?

I think David is asking us to confirm whether trapping for an error on "Is in 
set" is a reliable means for determining whether the set exists. It "seems ok" 
but I wasn't able to find the 4D documentation that asserts that an error is 
thrown if the set doesn't exist. I don't think he necessarily wants us to run 
his code as provided, although given the pretty descriptive names of those 
methods it's not to hard to work out what they do.


> Now I assume that from the names of these methods that basically that if an 
> error occurs that 
> 
> ErrorHandler_SuppressError is called and that this method turns the process 
> variable Error to a number other than zero and that is how you figure out 
> whether the error was thrown and thus whether 
> 
> Is in set()threw an error.

To be fair the Error process variable is a built-in 4D system variable so it 
would be 4D that is setting its value rather than David's error handler. I 
suspect David's method could actually contain nothing, although knowing him it 
probably contains some sort of logging. That said, 4D do suggest copying the 
Error variable into your own process variable if you need to reference it 
outside of the error handler method: 
http://livedoc.4d.com/4D-Language-Reference-16-R3/Interruptions/ON-ERR-CALL.301-3217504.en.html


> For those who might have been confused in the fashion that I was, I would 
> offer this version of what I think David's code is that I think is clearer. 
> You might disagree:
> The method "ErrorIgnore" sets a inter-process variable (<>fErrorHappened) to 
> True

I don't know that the code is necessarily clearer but I would strongly 
discourage the use of an interprocess variable here. You could end up with an 
impossible to debug situation where two or more processes are updating/reading 
the state of this interprocess variable. Error handling is process-specific so 
should really use process-level variables.

Cheers
J
**
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**

Resetting The Explorer Window - Tip

2017-07-16 Thread Allan Udy via 4D_Tech

Hi All,

Here's a quick tip if you suddenly loose the buttons at the bottom of 
your Explorer window, as I did this afternoon -- I couldn't view method 
Comments  (no Preview/Comments button), nor could I Add [+] or Delete 
[-] methods etc -- those options were just not available to me.


What to do when your development environment goes belly up... and when a 
computer restart, software restart, and software reinstall don't solve 
the problem?


1. Close the Explorer window

2. Hold the Shift key down, and

3. Select the menu item:   Design >  Explorer >  Methods

This has the effect of 'resetting' the size and location of the Explorer 
window, and thankfully, making the buttons at the bottom of the screen 
'magically' reappear.


Spent over half an hour trying to find any info about this, and trying 
to work out where my buttons and options had disappeared to.  Found the 
solution above by luck, although you could say it was found because of 
nearly thirty years of experience ;-)


Hope this helps someone else sometime.  Still don't know where my 
buttons went, or why


Cheers,
Allan Udy

Golden Micro Solutions Ltd, Blenheim, New Zealand
http://www.golden.co.nz






Cheers,
Allan Udy

Golden Micro Solutions Ltd, Blenheim, New Zealand
http://www.golden.co.nz

**
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**

Re: Print Project Form

2017-07-16 Thread Keisuke Miyako via 4D_Tech
the command is called Print form, it can not be more obvious!

http://doc.4d.com/4D-Language-Reference-15.4/Printing/Print-form.301-3273939.en.html

> 2017/07/17 6:26、Robert Livingston via 4D_Tech <4d_tech@lists.4d.com> のメール:
> Is it possible to print a project form?




**
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**

Print Project Form

2017-07-16 Thread Robert Livingston via 4D_Tech
Is it possible to print a project form?

When I review the "print" functions, they always seem to refer to table forms.

I suppose I can use some table form in some "pseudo table" for what I am trying 
to do, but it would be more straight-forward if I could just print a project 
form


Thanks
**
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**

Re: Thinking through object/text fields: Findings summarized, advice solicited

2017-07-16 Thread Julio Carneiro via 4D_Tech
Correct, David, you got the gist of my comment.

Jim Hays gave a great example where I can see object fields excel. If your app 
requires user defined fields, then an object field is just perfect for that. 
I’ve had similar situations in the past and used tab-separated text fields 
first, and then blob fields when that became available. Now object fields would 
be much much better because you can query on those ‘user defined’ fields, a 
great improvement over previous implementations.

julio

> On Jul 14, 2017, at 11:15 PM, David Adams via 4D_Tech <4d_tech@lists.4d.com> 
> wrote:
> 
> On Sat, Jul 15, 2017 at 7:36 AM, Kirk Brooks via 4D_Tech <
> 4d_tech@lists.4d.com> wrote:
> 
>> 
>> Perhaps this is what you are saying and I'm just reading too narrowly (it's
>> been that sort of week).
>> 
> 
> I'm not sure, but I was reading Julio's comment as  something akin to
> "David, don't do what you were offering as an example recently."
> Specifically, storing a zillion copies of what amounts to a record stuffed
> into an object and then an object field. Like, if you've *always* got first
> name, middle name, last name, put them in fields! Don't put them in an
> object that you then put into an object field. You can end up spending most
> of your space storing redundant data, namely the keys.
> 
> Now, if you have a bunch of different JSON formats, that's a different
> story. Some records might have first name, middle name, last name and
> others have interval length, start date, and end date. I don't know, I'm
> just making something up.
> 
> The other day I started my experimentation on object field with some code
> I'd written. It generated zillions of objects, some in an array and some as
> summaries of the array. I thought, hey! I'll store these and then can bring
> the results back for different sorts of analysis later. Sure, why not? I
> stuffed them into object fields and they were absolutely ginormous. So, I'd
> have a record with a field with 96 array elements (24 hours broken into 15
> minute buckets with stats for that interval)...and most of the data is just
> the structure of the data...which is the same for every record. It's
> obviously a lot more efficient to store the findings in proper tables,
> boiled down to a more compact representation, or boiled down to a more
> compact representation and stuffed into a blob as UTF8, or exported and
> compressed. Whatever.
> 
> So, I was talking about what is called a "stupid example." I believe that
> is the correct, contemporary term of art...but it's exactly the sort of
> mistake someone else might make, so it's worth thinking about. If you have
> an entirely regular structure, why would you store it in an object field? I
> have a weird situation where the goal is to store JSON itself, but leave
> that out. What is the point of storing your data in an object field?
> (Thomas Maul and others also made a point like this on the Forums, unless
> I'm mis-paraphrasing.) It doesn't generally make any sense. Here:
> 
> {"total":5}
> 
> If you store this in every single record in a table, what do you gain?
> Well, nothing, so far as I can see. instead, put it in a regular field
> named "total". Then you don't need to store the string "total" with every
> record (the field name itself is the 'key') and the number is stored
> directly as a number (more compact, easier to get into arrays, etc.)
> 
> I really have no idea how people are using object fields. 4D has some
> demos. I've asked several times in different venues for several months and
> have had very little response. So, I suspect that people mostly haven't had
> a chance to get to V16 and use them yet. That makes this a good time to
> think them through.
> 
> More thoughts and comments wanted! It would be helpful to everyone to hear
> real-world stories about how you're finding object fields helpful. For my
> money, I'm not likely to use them much. But, like any tool, it's good to
> know how they work so that you can fit them to purpose. When there's a good
> time to use an object field, I'll be glad to have already thought the
> subject through enough to recognize the situation immediately.
> 
> Just to keep things in one place, here's where I can imagine using object
> fields:
> 
> * Storing prefs, etc. Don't know if this is "proper" but it sure feels like
> a good idea. I often use external JSON files for configuration data anyway.
> Very handy.
> 
> * Storing messaging data. If I were to write another distributed,
> record-based, task or message queue in 4D, I'd stuff the job/message data
> into an object field in a heartbeat. That's a perfect use.
> 
> Where I won't use them, of don't expect to, is for making what amount to
> "repeating fields." You know
> 
> Quarter_1_Total
> Quarter_2_Total
> Quarter_3_Total
> Quarter_4_Total
> 
> ...and then the financial years changes and you have to push figures down,
> etc. That's just a bad design. I'm also now terribly likely to use them for
> things like 

Re: Set_Exists() function: Simple version

2017-07-16 Thread Robert Livingston via 4D_Tech
When David writes I generally find it very clear if it is discussing something 
that is basic enough for me to have  a chance to understand in the first place. 

But I found this  message a little confusing and yet sets seem to be a fairly 
basic topic.


> On Jul 14, 2017, at 5:10 PM, David Adams via 4D_Tech <4d_tech@lists.4d.com> 
> wrote:
> 
> I was just consolidating some old code and ran across something that I
> wrote some time back called Set_Exists. No clue. It seems to work, but I
> can't say why.

No clue??  I cannot say why?? I am not sure whether this is a joke that I don't 
get or what.

It would seem to be fairly clear that the basic logic here is to use the 

Is in set()Command to test for whether a set exists. The documentation says 
that if a set does not exist, then this will throw an error. So the code is 
taking advantage of this

(Interesting, as a sidelight, the command:Records in Set() does NOT throw 
an error if the set does not exist. Rather it just returns 0. Unfortunately, 
use of this command does not allow you to distinguish whether the set exists 
and is empty or whether the set does not exist at all. If it returns a number 
greater than 0 then you know the set exists, but that is not quite enough)

So David is using: Is in setto throw an error when the set does not 
exist.

Then he asks us to confirm if the code is reliable. But there are three methods 
included in the code

ErrorHandler_Install
ErrorHandler_SuppressError
ErrorHandler_InstallPrevious

that we are not given. How am I supposed to test it?


Now I assume that from the names of these methods that basically that if an 
error occurs that 

ErrorHandler_SuppressError is called and that this method turns the process 
variable Error to a number other than zero and that is how you figure out 
whether the error was thrown and thus whether 

Is in set()threw an error.

I cannot see how this would not be reliable  if I am interpreting David's code 
correctly



****************
**

For those who might have been confused in the fashion that I was, I would offer 
this version of what I think David's code is that I think is clearer. You might 
disagree:
The method "ErrorIgnore" sets a inter-process variable (<>fErrorHappened) to 
True


  // PROJECT METHOD: rfSetExist  PATH: rfSetExist
  // PARAMETERS
  // $1 = Set name being tested
  // 
  // RETURNED VALUE(s)
  //$0 Type: Boolean
  //    
  // DESCRIPTION: Tells you whether a set exists. If it returns True then the 
set exists.  ( rf is a personal naming convention for "returns flag")


C_BOOLEAN($0;$setDoesExist)
C_TEXT($1;$setName)
C_BOOLEAN($testInSet)

$setName:=$1

<>fErrorHappened:=False  // this is a global that is created at startup

ON ERR CALL("ErrorIgnore")  // ErrorIgnore is a method that sets 
<>fErrorHappened to true
$testInSet:=Is in set($setName)  // if the set does not exist, this will throw 
an error. This particular "Set" command is sensitive as to whether the set 
exists
ON ERR CALL("")

If (<>fErrorHappened)
$setDoesExist:=False
Else 
$setDoesExist:=True
End if 

$0:=$setDoesExist


****************
**







> 
> C_BOOLEAN($0;$exists)
> C_TEXT($1;$set_name)
> 
> $set_name:=$1
> 
> Error:=0
> 
> ErrorHandler_Install ("ErrorHandler_SuppressError")
> 
> C_BOOLEAN($is_in_set)
> $is_in_set:=Is in set($set_name)
> 
> ErrorHandler_InstallPrevious
> 
> $exists:=Error=0  // You could test for error 39 to be a bit more specific.
> 
> $0:=$exists
> 
> Here's a little routine I wrote to try it out:
> 
> ALL RECORDS([Cart])
> CREATE SET([Cart];"Cart_All")
> REDUCE SELECTION([Cart];0)
> UNLOAD RECORD([Cart])
> 
> $this_returns_true_correctly:=Set_Exists ("Cart_All")
> 
> $this_returns_false_correctly:=Set_Exists ("Foo")
> 
> Obviously, you would need to use a table name that exists in your structure
> to check this out.
> 
> Can anyone confirm/deny that this code is reliable? Seriously, I have no
> memory of writing this...Not that unusual for me, frankly...I tend to punch
> out reams of code/writing and don't always look back.

**
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**