Is it possible to prevent the reading and/or setting of a field value with DBIx Class? - perl

I'm working in a project that uses Catalyst and DBIx::Class.
I have a requirement where, under a certain condition, users should not be able to read or set a specific field in a table (e.g. the last_name field in a list of users that will be presented and may be edited by the user).
Instead of applying the conditional logic to each part of the project where that table field is read or set, risking old or new cases where the logic is missed, is it possible to implement the logic directly in the DBIx::Class based module, to never return or change the value of that field when the condition is met?
I've been trying to find the answer, and I'm still reading, but I'm somewhat new to DBIx::Class and its documentation. Any help would be highly appreciated. Thank you!

I‘d use an around Moose method modifier on the column accessor generated by DBIC.
This won‘t be a real security solution as you can still access data without the Result class, for example when using HashRefInflator.
Same for calling get_column.
Real security would be at the database level with column level security and not allowing the database user used by the application to fetch that field.
Another solution I can think of is an additional Result class for that table that doesn‘t include the column, maybe even defaulting to it and only use the one including the column when the user has a special role.

Related

How do I specify the User-Defined Table Type for a property with Insight Database

I have a pretty simple stored procedure to just update the status value for a bunch of records. I send in an unknown value of record IDs and it works.
I love using Insight.Database and wouldn't want to use anything else if possible.
The problem is our DBA's created multiple User-Defined Table Types to handle situations. But their naming conventions are identical.
We have a [IntTable] with column [IntValue]
and another [TinyIntTable] with column [TinyIntValue]
Insight appears to inspect the type of UDT that could work. And sometimes it chooses [TinyIntTable] (I am guessing because the values in the array being sent are all small enough to fit into a tinyInt. But that [TinyIntTable] isn't compatible with the stored procedure. How do I force Insight.Database to always use the [IntTable]?
Is there an attribute I could use on my c# object definition?
If you’re using stored procedures, then insight will check the type of the parameter and use the correct one. i.e. it should just work.
So your problem is likely something else. Check out the table type section on the wiki, and if that doesn’t solve it for you, please post a simple example on github and we’ll help you out.

Can I avoid a relation loop in my database design?

I try to design database tables for the case shown below. I also have an account defined, but it's not important regarding my problem.
There is a list of operations (expenses). Each operation can take place in specified POI, places can be grouped in chains (optional). Each operation can have a recipient, specifically a shop chain.
My current design looks like below. I could even remove chain table in favor of direct reference to recipient, but it still leaves a loop between tables. Effectively, single row could contain references to place and receiving account having different recipient defined.
The only solution I can see is a table check to exclude described case, but I'm wondering: is there a better fix?
As far as I can tell there isn't anything fundamentally wrong with your design. There's no need to change it just because it contains a loop. The loop in this case doesn't even appear to be a circular dependency. If you believe your current design accurately models what it is intended to then I see no need to change it.

Updating a field of an Access table with data from form

I am working on Access 2007. I have a table with some fields in it. I had created a form from the table and one of the fields of the table is a concatenation of 2 fields from the same table.
There are 2 fields OppNo and Material in the table. I had created a form with these (and others in the table) fields. There is another field OppMat which is blank in the table. However, I had got the data into OppMat field populated as a concatenation of OppNo and Material fields in the form. I am now looking at having the table updated with the data of OppMat from the form to the same corresponding field in the table.
Kindly advise as how I could achieve this.
Thanks and regards,
This might be possible if these cases are met:
The field OppMat ALWAYS has the same structure and you can assure that it does.
Users will not be able or very unlikely to deviate from this structure.
Notably you should use something like Left(), Right(), Mid() and so on. Whatever works best for your structure. You can use the string modifiers: https://msdn.microsoft.com/en-us/library/dd789093.aspx
On the other hand I must admit that I am sceptical if your solutions is the best. Here are my reasons:
Users are unpredictable and will continously deviate from your intended way to use the application.
Using the string functions and fixating on one structure makes your code construction inflexible, hard to maintain if changes occur and prone to errors.
The alternatives seem to be better with little drawback.
My suggestions for alternatives:
Use one textbox for each field so that you have two textboxes. You can even position them that way that it almost looks like it is continous text. But not too much otherwise the user will beconfused.
You can add a label that shows your concatenated fields. But for input you use two different textboxes.
Cheers!

How do you created a nested form using HTML::FormHandler in Catalyst?

I have a situation where we have a base recordset with about one hundred thousand records. And, we are creating a separate application that shares some of the dataset, but not most, so we are creating a detail table that has a one to one relationship with the original table. What I want to do is pull the existing information from the original table and display it as read only, but I want the fields in the detail table to be writeable.
I've started by creating a listing with the contents of the original table, I want the user to be able to seemlessly hit "edit" by an entry and be taken to the form to create the detail record, click save, and have it update, or create the record.
So, what is the best way to do this?
This question is old, but in order to help future searchers...
Including a related table in a form is handled automatically if your DBIx::Class result sources are correctly setup. A related table can be pulled into the form by simply defining a compound field using the relationship name of the other field and defining subfields with the names of the columns in the related table.
See: HTML::FormHandler::Manual::Fields
And: HTML::FormHandler::Manual::Database
This isn't a real answer, in that I can't really provide you with a solution, but I can hopefully provide you with somewhere to start. I think you need to define a form in HTML::FormHandler which represents a single row from your detail table, then build your read-only form from multiple instances of single-row form. This article describes the problem and a partial solution much better than I have:
http://catdev.blogspot.com/2009/05/defining-form-processing-problem.html
I'm fairly new to Perl and HTML::FormHandler, and there's a good chance that there is a better way of doing this. It's a problem that I have solved 'manually' in PHP before, but one which I am sure I will come across in Perl.

Options for handling a frequently changing data form

What are some possible designs to deal with frequently changing data forms?
I have a basic CRUD web application where the main data entry form changes yearly. So each record should be tied to a specific version of the form. This requirement is kind of new, so the existing application was not built with this in mind.
I'm looking for different ways of handling this, hoping to avoid future technical debt. Here are some options I've come up with:
Create a new object, UI and set of tables for each version. This is obviously the most naive approach.
Keep adding all the fields to the same object and DB tables, but show/hide them based on the form version. This will become a mess after a few changes.
Build form definitions, then dynamically build the UI and store the data as some dictionary like format (e.g. JSON/XML or maybe an document oriented database) I think this is going to be too complex for the scope of this app, especially for the UI.
What other possibilities are there? Does anyone have experience doing this? I'm looking for some design patterns to help deal with the complexity.
First, I will speak to your solutions above and then I will give my answer.
Creating a new table for each
version is going to require new
programming every year since you will
not be able to dynamically join to
the new table and include the new
columns easily. That seems pretty obvious and really makes this a bad choice.
The issues you mentioned with adding
the columns to the same form are
correct. Also, whatever database you
are using has a max on how many
columns it can handle and how many
bytes it can have in a row. That could become another concern.
The third option I think is the
closest to what you want. I would
not store the new column data in a
JSON/XML unless it is for duplication
to increase speed. I think this is
your best option
The only option you didn't mention
was storing all of the data in 1
database field and using XML to
parse. This option would make it
tough to query and write reports
against.
If I had to do this:
The first table would have the
columns ID (seeded), Name,
InputType, CreateDate,
ExpirationDate, and CssClass. I
would call it tbInputs.
The second table would have the have
5 columns, ID, Input_ID (with FK to
tbInputs.ID), Entry_ID (with FK to
the main/original table) value, and
CreateDate. The FK to the
main/original table would allow you
to find what items were attached to
what form entry. I would call this
table tbInputValues.
If you don't
plan on having that base table then
I would use a simply table that tracks the creation date, creator ID,
and the form_id.
Once you have those you will just need to create a dynamic form that pulls back all of the inputs that are currently active and display them. I would put all of the dynamic controls inside of some kind of container like a <div> since it will allow you to loop through them without knowing the name of every element. Then insert into tbInputValues the ID of the input and its value.
Create a form to add or remove an
input. This would mean you would
not have much if any maintenance
work to do each year.
I think this solution may not seem like the most eloquent but if executed correctly I do think it is your most flexible solution that requires the least amount of technical debt.
I think the third approach (XML) is the most flexible. A simple XML structure is generated very fast and can be easily versioned and validated against an XSD.
You'd have a table holding the XML in one column and the year/version this xml applies to.
Generating UI code based on the schema is basically a bad idea. If you do not require extensive validation, you can opt for a simple editable table.
If you need a custom form every year, I'd look at it as kind of a job guarantee :-) It's important to make the versioning mechanism and extension transparent and explicit though.
For this particular app, we decided to deal with the problem as if there was one form that continuously grows. Due to the nature of the form this seemed more natural than more explicit separation. We will have a mapping of year->field for parts of the application that do need to know which data is for which year.
For the UI, we will be creating a new page for each year's form. Dynamic form creation is far too complex in this situation.