Partial Modification class conditions behavior - a small exploration

I was looking at adding some validation to a database column that couldn’t (easily) go into the database constraints so I was doing it in the modification class. Since i wanted this to take place on update and insert, i thought i would have to write two functions (one to check the insert modification’s property directly, and one to check either the update modification’s property, or if that was unset, to check the row from the database). While looking at other examples of this kind of check, i found this, which i thought was curious:

partial void postInsert() {
    postModify( BooksTableRetrieval.GetRows( conditions.ToArray() ) );
}

partial void postUpdate() {
    postModify( BooksTableRetrieval.GetRows( conditions.ToArray() ) );
}

Now why is that? (Or so i thought to myself.) The conditions array isn’t set during an insertion, is it? How can we pass that to the GetRows query if there’s nothing in it, it should complain! So i investigated.

It turns out that the insert function acts (as @samrueby suggested it may) in a way that it populates the conditions array upon insertion, with an id condition for the newly inserted row. Yay! That makes sense! Now i know why the conditions array is useful after an insert.

One interesting thing that i found out - behavior i didn’t expect - was that it also does this for updates. So, if you update rows with conditions that match the table in a non-id way (say you match a book by title and author and isbn instead), it then throws those conditions out the window and replaces the conditions array with an ID condition only.

Well, this has been “exploring internals” with brendan. Thank you for your time!

2 Likes

Great post, @brendan. I hope that details like the insert condition thing make developing with EWL a great experience.

Are you sure the conditions get overridden for updates, too? I don’t remember ever writing that, and I just took a quick look at StandardModificationStatics and I don’t see any logic to make it happen.

Not at all sure! This is what i’m seeing,

conditions = new List<CommandConditions.BooksTableCondition>();
conditions.Add( new CommandConditions.BooksTableEqualityConditions.BookId( BookId ) );

That seemed pretty clear!

Ah! I think i must have stepped through stale code, apologies. You’re correct, i just re-ran update-d…logic and stepped through again - found the update case, where it does indeed add a condition to the list rather than tossing the conditions out the window. Clarity gained!

So what you’re saying is that update uses the original conditions… And adds the primary key conditions?

…Yessir!

I wonder if that hurts performance.

Are you sure it does anything to the conditions in the update case? If so, I wasn’t aware of it. Can you point me to a line in StandardModificationStatics?

“Sure”? Nope, I already misread the code once and just now was going off of what I was saying, not a fresh trying-to-look-at-code, so surety isn’t something I’ve got!

I’ll take a look and see what I can see on the morrow.

Yeah, no the trouble is that i evidently can’t read.

Nothing is done to the conditions array on an update except iteration. There’s nothing added to it.

That’s good. Alright, so what we learned from this is that it’s safe to use the conditions array implementing pre/postInsert in a Modification class.

Wait. How can it possibly work on preInsert?

(Before I put my foot in my mouth again, let me say that I’m not looking at the code right this minute)

I don’t think it can - the array is updated right after the database call I think.

1 Like

Does that sound accurate @wgross? That would be important to write down.

Yeah i looked through it and it adds the condition (Well, creates the conditions list and adds the primary key condition) between the pre and post functions.

Yes, @samrueby, I think @brendan is correct that no conditions are available during preInsert. I don’t think this has ever caused me trouble. It wouldn’t make much sense to have conditions before you’ve actually put anything in the DB.

Couldn’t people easily make an undetectable mistake?

What’s an example of a mistake someone could make?

foreach (var row in TableRetrieval.GetRows(conditions.ToArray()) { // Yields no results, never enters loop
// Important check to make sure of data integrity that the database wouldn't be able to handle on its own
}

Ok, good example. Maybe we could have it blow up if you try to access conditions in preInsert, or something.

1 Like