How to generate dynamic values in fitnesse - fitnesse

I have to insert incremental values in a column of the table using Fitnesse. The incremental value I'll get from a stored procedure which returns the last inserted value. So I have to increment the value and store it.
For example: I'll get a value from the stored procedure output. And I have to increment the value by 1 and insert into the table.
Any ideas?
Output from stored procedure is like : ACRDE0001 (PK)
Value to store in table : ACRDE0002, ACRDE0003, .....
Expected output
!|insert|table1|
|col1|col2|col3|
|ACRDE0001|abc|def|
|ACRDE0002|abc|def|
|ACRDE0003|abc|def|
.
.
.
.

As far as I'm aware the only way to change (e.g. increment) a value you get during your test is by writing some code in a fixture. There is a pull request to allow more dynamic Slim expression directly in the wiki, but that has not been merged (let alone released) yet.
Your questions suggests that the value is something you get from a database and that you then want to send back the generated/incremented value with new records you insert. In that case I wonder whether the increment is actually that useful to actually have in your wiki (your test case is not about the generated values, is it?).
Maybe your fixture could just retrieve the initial value (or have it supplied as constructor value) and the fixture could generate the a new value for each row and send them to the database.

Related

inserting a row having no values for Primary Key columns fails

For the following table:
I run the following stored procedure:
I'm redirected to "Results" tab and seeing nothing. Then if I click on "refresh" icon (below Results tab), then I get the dialog saying:
SQLCODE = -625 validation error for column ID, value "* null *"
And of course, nothing is added...
As far as I understand, firebird expects somevalue for RC_ID (which is my PK and should principally automatically incremented). If I give value also for RC_ID, it is working well.
So, what should I do to make a clear "insert" without these errors?
The problem is that you are not setting a value for the primary key. Contrary to your expectation, primary keys are not automatically incremented. This is the case in any database I'm aware of. You always need to mark it as an identity, auto increment or generated, or something else to get that behavior, although some tools (table builders) may already apply this for you by default.
If you are using Firebird 3, you can define your column as GENERATED BY DEFAULT AS IDENTITY (see Identity Column Type in the Firebird 3 release notes). For earlier Firebird versions the best way is to define a sequence (also known as generator) with a before insert trigger that populates the primary key column.
For more details on how to define an identity column (or define the trigger), see my answer on this question: Easiest way to create an auto increment field in Firebird database.
In firebird, the autoincrement was not working like in MySQL. Thus, sending a value for RC_ID was a must...
I found some working examples based on idea:
create a generator
assign it to column (PK)
call GEN_ID with that generator like this:
:
begin
insert into RESERVATIONCATEGORY (RC_ID, RC_NAAM)
values (
GEN_ID(GEN_RESERVATIONCATEGORY _ID,1), 'selam'
);
suspend;
end

Ambiguous cache keys

I have a data structure which is like this (the real has more nodes levels):
-------Node 1------
| |
| |
Node A: Node B:
-element 1A1 -element 1B1
-element 1A2 -element 1B2
Each element is identified by parents IDs. Each node and element may store or may don't store some value. The values are inherited from parents. So when I want to find value for 1A2, I:
1) check if value for 1A2 exists
2) if not, check if value for A exists
3) if not, check if value for 1 exists
4) save the first found value
The structure is stored in database and it's much more complex. So the problem is that database queries are too slow. But this structure doesn't change often, so I decided to build a server-side cache for it. The cache is removed after any changes in the structure and is rebuild when there is the first attempt to read value of some element. The problem is that, when the cache keys are like this:
"1-A-1" for 1A1 value
"1-A-2" for 1A2 value
"1-A" for A value
"1" for 1 value
1A has value and 1A1 doesn't have value but 1A2 does, the first cache stored is "1-A". Then when I try to find value for 1A2, I first search through the cache and there I find the key "1-A" which fits for my element as these are right nodes. So I don't make any query to database as I assume, the value found in the cache is right. But it is not.
How can I solve this problem? Is there any solution? I want to make the least queries as possible, but I always want to find the exact value for given element.

Recognize the type of the parameters of a user defined sql to be used in a Delphi TQuery at runtime

I'm writing a delphi(7 ver) application and in some place I want to execute parameterized queries (for BDE and Paradox) which will be loaded at runtime into a TQuery by the user. These queries will be stored in text files (one text file for one query). The application then, will construct for any parameter of the query, one input control (Tedit) in order to be able to accept values by the user. Also there will be a button for the execution of query. My question is how can I recognize the datatype of the query's parameter? Is there a way to get this type without of cause to be included in some way in the text file containing the query?
Create a second query from the first, but modify its where clause to ensure no rows.
SELECT * FROM MYTABLE WHERE PKFIELD IS NULL
Name your parameters so that you can establish their datatypes from the fieldtypes of this second query.
I realise this only works for relatively simple cases, but it should get you some of the way.
the advantage of using a parameter is that you don't need to know its data type.
Use the string value from the tedit
"select * from mytable where myfield = :param1"
"parambyname('param1').asstring := edit1.text"
I've made this with MySQL database. you must define some parameters, Exemple:
SELECT * FROM MyTable WHERE MyField=[ANNEE];
in this case, i have an other table, called balise, that look like this
"ID" "BALISE" "CAPTION" "DEFAULT_VALUE" "CNDT" "COMPOSANT"
"1" "ANNEE" "Année" "2014" "Properties.MaxValue=2014||Properties.MinValue=2007" 1;
in runtime, this mean that:
Make in my Panel, a TLablel that have caption Année
Make in the same line an other component type 1 (That mean in my case TcxSpinEdit), this component have défault value 2014, have Two properties Max Value=2014 and Min Value=2007, (I use RTTI to modifie this value of parameters, in Delphi ver7, use TypeInfo).
An Other Button with function called Actualise, this function have Original query, must browse an array of TBalise that i have created, take the value (In my case, take TcxSpinEdit(MyObject).Value), and replace it in the copy of my query (AnsiReplaceStr(Requete, '[ANNEE]', MyValue)), so i have the final query to execute it.
I have module in complete projet, worked with this methode, and it workk fine.

Ruby on Rails+PostgreSQL: usage of custom sequences

Say I have a model called Transaction which has a :transaction_code attribute.
I want that attribute to be automatically filled with a sequence number which may differ from id (e.g. Transaction with id=1 could have transaction_code=1000).
I have tried to create a sequence on postgres and then making the default value for the transaction_code column the nextval of that sequence.
The thing is, if I do not assign any value to #transaction.transaction_code on RoR, when I issue a #transaction.save on RoR, it tries to do the following SQL:
INSERT INTO transactions (transaction_code) VALUES (NULL);
What this does is create a new row on the Transactions table, with transaction_code as NULL, instead of calculating the nextval of the sequence and inserting it on the corresponding column. Thus, as I found out, if you specify NULL to postgres, it assumes you really want to insert NULL into that column, regardless of it having a default value (I'm coming from ORACLE which has a different behavior).
I'm open to any solution on this, either if it is done on the database or on RoR:
either there is a way to exclude attributes from ActiveRecord's
save
or there is a way to change a column's value before insert with a trigger
or there is a way to generate these sequence numbers within RoR
or any other way, as long as it works :-)
Thanks in advance.
For the moment, you might be stuck fetching and assigning the sequence in your ROR model like this:
before_create :set_transaction_code_sequence
def set_transaction_code_sequence
self.transaction_code = self.class.connection.select_value("SELECT nextval('transaction_code_seq')")
end
I'm not particularily fond of this solution, since I'd like to see this corrected in AR directly... but it does do the trick.
If you want to insert the default value in to a column in an INSERT statement, you can use the keyword DEFAULT - no quotes:
INSERT INTO mytable (col1, col2) VALUES (105, DEFAULT);
Or you could spell out the default, nextval(...) in your case. See the manual here.
A trigger for that case is simple. That's actually what I would recommend if you want to make sure that only numbers from your sequence are entered, no matter what.
CREATE OR REPLACE FUNCTION trg_myseq()
RETURNS trigger AS
$BODY$
BEGIN
NEW.mycol := nextval('my_seq');
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
CREATE TRIGGER myseq
BEFORE INSERT
ON mytable
FOR EACH ROW
EXECUTE PROCEDURE trg_myseq();
On a side note:
If you want to assign your own (non-sequential) numbers as 'sequence', I have written a solution for that in an answer a couple of days ago:
How to specify list of values for a postgresql sequence
I was still experiencing this issue with Rails7 - I could see that Rails was generating a NULL in the insert, but changing the column from integer to bigint solved it. - Rails then does not supply a value for my sequenced column and the DEFAULT nextval('number_seq') is used.

Data type mismatch in foxpro stored procedure

I want to make a copy of every record inserted in jobact to a new table jobactupdates. I am using a stored procedure for this purpose. Both tables are exactly the same and have same no of columns. When I insert data in jobact using insert query then, the stored procedure fails and show the Data Type mismatch error.
My code looks like this:
PROCEDURE insertData
INSERT INTO jobactupdates (jobcode ,jobdescr ,fileno ,port ,mastcode ,mastdescr ,mastdescr1 ,shipper ,goods ,unit1 ,qty ,unit ,vesname ,arremarks ,arrdate ,remarks ,docstat ,docdate ,blno ,bldate ,jastat ,rate ,demand ,received ,balance ,transpor,dldate);
VALUES(jobact.jobcode,jobact.jobdescr,jobact.fileno,jobact.port,jobact.mastcode,jobact.mastdescr,jobact.mastdescr1,jobact.shipper,jobact.goods,jobact.unit1,jobact.qty,jobact.unit,jobact.vesname,jobact.arremarks,jobact.arrdate,jobact.remarks,jobact.docstat,jobact.docdate,jobact.blno,jobact.bldate,jobact.jastat,jobact.rate,jobact.received,jobact.balance,jobact.transpor,jobact.dldate);
ENDPROC
A Data Type Mismatch error occurs when you try to insert an inappropriate data type into a field. For example, if you try to store a string into an integer field. I would double check the table structures and confirm that they are identical.
Another thing to be aware of is if any of the JOBACT field types are set to Integer (AutoInc). They will have to be set to just Integer in the JOBACTUPDATES table. Otherwise you will get a "Field is read-only" error message.
For
Character fields: write them into '' marks,
Numeric fields: just numbers for example 123,
Date fields: {^yyyy-mm-dd}
(There can also optionally be time in Date field.)
Is this your actual query? If so, the fact your Columns and Values clauses contain different field lists has certainly caused this error:
Insert Into ...
bldate,
jastat,
rate,
demand,
received,
balance ..
Values ...
jobact.bldate,
jobact.jastat,
jobact.rate,
jobact.received, <--
jobact.balance, <--
jobact.transpor <--
.

Resources