Eiffel: compilation error `Source of assignment is not compatible with target` - eiffel

With complete void check set in compiler I've got a Variable is not properly set compilation error on following case which for me is right (in my mind). It says that the source of assignment is not compatible with target. What am I missing here??? (DB_SERVICE.load_from_primary_key...)
Class DB_SERVICE
deferred class
DB_SERVICE [G -> DB_ENTITY create make_from_db_result end]
inherit
ACTION
redefine
start,
execute
end
LOGGABLE
rename
make as make_from_loggable
end
feature -- Creation
make (a_db_connection: attached DB_CONNECTION)
require
valid_db_connection: a_db_connection.is_connected
do
make_from_loggable
db_connection := a_db_connection
create last_items.make (100)
create last_column_names.make_empty
ensure
db_connection_setted: a_db_connection = db_connection and db_connection.is_connected
end
feature -- Access
item: detachable G
db_connection: DB_CONNECTION
last_items: HASH_TABLE[like item, INTEGER] -- content of last resultset
last_column_names: ARRAY[STRING] -- Column names of last resultset
feature -- status_report
load_from_primary_key (primary_key: INTEGER)
-- Loads given item into item otherwise item will be Void
require
attached db_connection.base_selection
local
l_db_result: DB_RESULT
do
if attached db_connection.base_selection as bs then
bs.query ("SELECT * FROM " + ({attached like item}).out + " WHERE " + {attached like item}.Primary_key_db_column_name + "=" + primary_key.out)
if bs.is_ok then
bs.load_result
create item.make_from_db_result(last_column_names, bs.cursor)
else
item := Void --HERE is the compiler complaining!
logger.write_critical ("Error while retreiving " + ({like item}).out + " from DB")
end
else
item := Void
logger.write_error ("base_selection is void")
end
end
end -- class
Class COMPANY_SERVICE
class
COMPANY_SERVICE
inherit
DB_SERVICE[COMPANY]
redefine
make
end
...
Class COMPANY
class
COMPANY
inherit
DB_ENTITY
rename
primary_key as id,
set_primary_key as set_id,
Primary_key_db_column_name as Id_db_column_name
redefine
make,
make_from_db_result,
out
end
create
make,
make_from_db_result
....

The type declaration detachable G indicates that if the corresponding actual generic is a reference type, the variable of that type could be detachable. In that case it would be OK to assign Void to such a variable. However, it's also possible that the actual generic is an expanded type. Prefixing an expanded type with detachable has no effect, the type remains the same and the variable cannot be assigned Void.
As an example, let's consider a simpler case, when there is no formal generic constraint for the parameter G. An actual generic could be STRING, and the variable item has a type detachable STRING. In this case, it's OK to assign Void to item.
Now, if the actual generic is INTEGER, the variable has a type detachable INTEGER that is equivalent to INTEGER. Assigning Void to a variable of this type makes no sense and is not permitted by the language rules.
The variable item still can be set to Void if the actual generic parameter is a reference type. For that, a local variable with the same type can be declared and its value can be assigned to item:
local
default_item: like item
do
item := default_item

Related

Eiffel: How to get class of a Void object? is it possible?

I have a void object which I declared, but want to get its class name is it possible??
item: detachable DB_ENTITY
db_connection.base_selection.query("SELECT * FROM " + item.generating_type.out)
Creating it is not what I want...
A type object (i.e. an object like the one returned by generating_type for an existing object) can be obtained using curly braces enclosing the type name:
{MY_TYPE}
In your example it would be {attached like item} if item is a feature (of type detachable DB_ENTITY to allow for a value Void), or {DB_ENTITY} if item is a local variable, so that the whole expression would read in one of the following ways:
db_connection.base_selection.query("SELECT * FROM " + ({attached like item}).out)
db_connection.base_selection.query("SELECT * FROM " + ({DB_ENTITY}).out)
In the second case, the corresponding string would be equivalent to "SELECT * FROM DB_ENTITY".
I would use
item_type_anchor: detachable DB_ENTITY
-- `item_type_anchor' for Current.
and then
db_connection.base_selection.query ("SELECT * FROM " + ({like item_type_anchor}).generating_type.out)
This means that the feature `item_type_anchor' clearly communicates that it does not expect to be attached, but is there as a type-anchor reference only. Used with the static reference Alex pointed out, the story is now clear and concise. :-)

Weird data type mismatch error VBA [duplicate]

I need to pass a String array to set a class property using its setter method. Array was declared in Module and it's perfectly set the values using Redim Preserve. When calling the Class setter method it gives error. If I continued to without setting array data type it worked. But I need to declare the data type as String.
I received a compile error "Type mismatch: array or user defined type expected."
Module
Dim sPageDetails() As String
' set some values to array
' Declare class instance
dim x as new X
with x
.SetPageNumberDetails(sPageDetails) ' assume SetPageNumberDetails is the setter method in class X
end with
End module
'class module start X
Private pageDetails() as String
' Setter for pageDetails array
Public Sub SetPageNumberDetails(ByRef sPageDetails() As String)
pageDetails= sPageDetails
End Sub
' Getter for pageDetails array
Public Function GetPageNumberDetails() As String()
GetPageNumberDetails= pageDetails
End Function
.SetPageNumberDetails(sPageDetails)
Remove the parentheses:
.SetPageNumberDetails sPageDetails
Remain the parentheses and add explicit 'Call':
Call .SetPageNumberDetails(sPageDetails)
It took 5-10 CPU ticks (~30 nsec), but code wil be more readable, editable, auditable etc. And it is simply comme il faut...
.

Insert data into database with a method of a class

I am trying to create a method to insert data to the database but it does not work. I am trying to insert data by using add_person. Here is my code. The transparent table name is ZPERSON_20.
CLASS lcl_person DEFINITION.
PUBLIC SECTION.
METHODS:
add_person
IMPORTING
im_id TYPE zperson_20-person_id
im_name TYPE zperson_20-person_name
im_add TYPE zperson_20-person_address
im_type TYPE zperson_20-person_type.
PRIVATE SECTION.
DATA:
c_id TYPE zperson_20-person_id,
c_name TYPE zperson_20-person_name,
c_add TYPE zperson_20-person_address,
c_type TYPE zperson_20-person_type.
ENDCLASS.
CLASS lcl_person IMPLEMENTATION.
METHOD add_person.
DATA: it_emp TYPE STANDARD TABLE OF zperson_20.
DATA: wa_emp LIKE LINE OF it_emp.
wa_emp-person_id = c_id.
wa_emp-person_name = c_name.
wa_emp-person_add = c_add.
wa_emp-person_type = c_type.
INSERT INTO zperson_20 VALUES wa_emp.
ENDMETHOD.
ENDCLASS.
PARAMETERS:
v_id TYPE zperson_20-person_id,
v_name TYPE zperson_20-person_name,
v_add TYPE zperson_20-person_address,
v_type TYPE zperson_20-person_type.
DATA: lv_ref_person TYPE REF TO lcl_person.
START-OF-SELECTION.
CREATE OBJECT lv_ref_person.
CALL METHOD lv_ref_person->add_person(
im_id = v_id
im_name = v_name
im_add = v_add
im_type = v_type
).
I would say your issue is inside the add_person method, as you are reading the values from the member variables, instead of the method parameters. Those member variables will probably be empty in this case, leading to inserting errors due to an empty or duplicated id.
I believe that the code you are trying to achieve is the following:
REPORT ZRKD_BASE_WSLOADER.
CLASS lcl_person DEFINITION.
PUBLIC SECTION.
METHODS:
add_person
IMPORTING
im_id TYPE zperson_20-person_id
im_name TYPE zperson_20-person_name
im_add TYPE zperson_20-person_address
im_type TYPE zperson_20-person_type.
ENDCLASS.
CLASS lcl_person IMPLEMENTATION.
METHOD add_person.
DATA: wa_emp TYPE zperson_20.
//----> Here are the modifications <-------
wa_emp-person_id = im_id.
wa_emp-person_name = im_name.
wa_emp-person_address = im_add.
wa_emp-person_type = im_type.
INSERT INTO zperson_20 VALUES wa_emp.
ENDMETHOD.
ENDCLASS.
PARAMETERS:
v_id TYPE zperson_20-person_id,
v_name TYPE zperson_20-person_name,
v_add TYPE zperson_20-person_address,
v_type TYPE zperson_20-person_type.
DATA: lv_ref_person TYPE REF TO lcl_person.
START-OF-SELECTION.
CREATE OBJECT lv_ref_person.
CALL METHOD lv_ref_person->add_person(
im_id = v_id
im_name = v_name
im_add = v_add
im_type = v_type
).
Would be enough to create a commit method, which you then call, if You are really sure to save on db, or add this parameter as a flag to add person. If set, commit the transaction. The instruction for this is "commit work." and it is missing in the entire snippet. And without it nothing moves from Your actual LUW commit buffer to db.
Your method add_person is defined to take no arguments and you are passing it arguments. Basically there is a disagreement in call and the definition.
Can you post the whole code here?

Oracle object array initialization collection

I am trying to create an array of oracle object type and I am getting some initialization related error.
Below is the sample code
CREATE OR REPLACE TYPE rectangle AS OBJECT
(
-- The type has 3 attributes.
length NUMBER,
width NUMBER,
area NUMBER,
-- Define a constructor that has only 2 parameters.
CONSTRUCTOR FUNCTION rectangle(length NUMBER, width NUMBER)
RETURN SELF AS RESULT
);
CREATE OR REPLACE TYPE BODY rectangle AS
CONSTRUCTOR FUNCTION rectangle(length NUMBER, width NUMBER)
RETURN SELF AS RESULT
AS
BEGIN
SELF.length := length;
SELF.width := width;
SELF.area := length * width;
RETURN;
END;
END;
To run below is the sample script
set serveroutput on
DECLARE
r1 rectangle;
r2 rectangle;
type rect_arr is table of rectangle;
m_rect rect_arr;
BEGIN
m_rect.extend;
m_rect(1) := rectangle(10,20);
sop(m_rect(1).area);
END;
Below is the error on console----- I know it is related to initialization error, and tried various constructor and member function solutions but none help.
Error report:
ORA-06531: Reference to uninitialized collection
ORA-06512: at line 7
06531. 00000 - "Reference to uninitialized collection"
*Cause: An element or member function of a nested table or varray
was referenced (where an initialized collection is needed)
without the collection having been initialized.
*Action: Initialize the collection with an appropriate constructor
or whole-object assignment.
m_rect rect_arr := rect_arr();

Parameter Passing an Array of Type in Delphi

I'm trying to pass an array out of a class into my main program in Delphi. I'm having a bit of trouble with the data types and an hour scouring the web has found nothing to help me. It sounds a bit strange, but the more complex the answer the better (it's for a college project).
I have a class connected to SQL which reads an SQL Query into an array of a record Type declarations (sorry if it's a bit messy at the moment) :
Type TScout = Record
SNum, FName, SName, Gender, Address, HomeNum, MobNum,
SEmail, STel, Hikes, Nights, Med, Diet : String;
DoB, DoJ : String;
End;
Type TScoutArray = Array of TScout;
Type TScoutSQL = Class
Public
Procedure InitSQL;
Procedure GetRecords;
Function SendRecords : TScoutArray;
Private
ScoutsArray : TScoutArray;
ScoutConnection : TSQLConnection;
ScoutQuery : TSQLQuery;
End;
So the whole "Function SendRecords : TScoutArray;" isn't working, as on the other side I have the same 2 types (TScout and TScoutArray) declared exactly the same, I call the function:
ScoutArray := ScoutSQL.SendRecords;
And I get:
[Error] MembersUnit.pas(51): Incompatible types
Can anyone help?
I suspect that your problem is that you are declaring these types twice in separate units. Doing so results in distinct, incompatible types.
What you need to do is to:
Declare the types, in the interface section, of one unit only (unit A, say).
In another unit (unit B, say) that wants to use these types you add unit A to the uses clause.
Wrong way
var
badArray: array of TScout;
begin
badArray := ScoutSQL.SendRecords;
This won't work. array of TScout and TScoutArray, the latter being what SendRecords returns, are different types in Delphi/Pascal.
Right way
var
niceArray: TScoutArray;
begin
niceArray := ScoutSQL.SendRecords;

Resources