2018-03-15 12:49:06 +06:00
|
|
|
------------------------------------------------------------------------------
|
2020-06-09 00:55:25 +02:00
|
|
|
-- G N A T C O L L --
|
|
|
|
|
-- --
|
|
|
|
|
-- Copyright (C) 2020, AdaCore --
|
|
|
|
|
-- --
|
|
|
|
|
-- This library is free software; you can redistribute it and/or modify it --
|
|
|
|
|
-- under terms of the GNU General Public License as published by the Free --
|
|
|
|
|
-- Software Foundation; either version 3, or (at your option) any later --
|
|
|
|
|
-- version. This library is distributed in the hope that it will be useful, --
|
|
|
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
|
|
|
|
|
-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. --
|
|
|
|
|
-- --
|
|
|
|
|
-- As a special exception under Section 7 of GPL version 3, you are granted --
|
|
|
|
|
-- additional permissions described in the GCC Runtime Library Exception, --
|
|
|
|
|
-- version 3.1, as published by the Free Software Foundation. --
|
|
|
|
|
-- --
|
|
|
|
|
-- You should have received a copy of the GNU General Public License and --
|
|
|
|
|
-- a copy of the GCC Runtime Library Exception along with this program; --
|
|
|
|
|
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
|
|
|
|
|
-- <http://www.gnu.org/licenses/>. --
|
2018-03-15 12:49:06 +06:00
|
|
|
-- --
|
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
with GNATCOLL.Traces; use GNATCOLL.Traces;
|
|
|
|
|
with GNATCOLL.Utils; use GNATCOLL.Utils;
|
|
|
|
|
|
|
|
|
|
package body GNATCOLL.SQL.Orm.Impl is
|
|
|
|
|
|
|
|
|
|
Me : constant Trace_Handle := Create ("ORM");
|
|
|
|
|
|
|
|
|
|
function Get_Data
|
|
|
|
|
(Self : Forward_Cursor'Class) return Shared_List_Data_Access;
|
|
|
|
|
pragma Inline (Get_Data);
|
|
|
|
|
-- Return access to the data used by a list. The returned access is only
|
|
|
|
|
-- valid while the list exists.
|
|
|
|
|
|
|
|
|
|
-------------
|
|
|
|
|
-- Is_Null --
|
|
|
|
|
-------------
|
|
|
|
|
|
|
|
|
|
function Is_Null (Self : Orm_Element) return Boolean is
|
|
|
|
|
begin
|
|
|
|
|
return Self.Index = -1;
|
|
|
|
|
end Is_Null;
|
|
|
|
|
|
|
|
|
|
--------------
|
|
|
|
|
-- Get_Data --
|
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
function Get_Data
|
|
|
|
|
(Self : Forward_Cursor'Class) return Shared_List_Data_Access is
|
|
|
|
|
begin
|
|
|
|
|
-- Not very elegant, but this avoids duplicating this function for
|
|
|
|
|
-- both types of lists in all the generated packages.
|
|
|
|
|
-- The Unchecked_Access is safe because tagged types are always passed
|
|
|
|
|
-- by reference (ARM)
|
|
|
|
|
|
|
|
|
|
if Self in Forward_List'Class then
|
|
|
|
|
return Forward_List (Self).Data'Unchecked_Access;
|
|
|
|
|
elsif Self in Direct_List'Class then
|
|
|
|
|
return Direct_List (Self).Data'Unchecked_Access;
|
|
|
|
|
else
|
|
|
|
|
return null;
|
|
|
|
|
end if;
|
|
|
|
|
end Get_Data;
|
|
|
|
|
|
|
|
|
|
-------------------
|
|
|
|
|
-- Integer_Value --
|
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
|
|
function Integer_Value
|
|
|
|
|
(Self : Orm_Element'Class; Field : Field_Index) return Integer is
|
|
|
|
|
begin
|
|
|
|
|
if Current (Self.Current) /= Self.Index then
|
|
|
|
|
raise Cursor_Has_Moved;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
if Is_Null (Self.Current, Self.Column + Field) then
|
|
|
|
|
return Integer'First;
|
|
|
|
|
else
|
|
|
|
|
return Integer_Value (Self.Current, Self.Column + Field);
|
|
|
|
|
end if;
|
|
|
|
|
end Integer_Value;
|
|
|
|
|
|
|
|
|
|
------------------
|
|
|
|
|
-- Bigint_Value --
|
|
|
|
|
------------------
|
|
|
|
|
|
|
|
|
|
function Bigint_Value
|
|
|
|
|
(Self : Orm_Element'Class; Field : Field_Index)
|
|
|
|
|
return Long_Long_Integer is
|
|
|
|
|
begin
|
|
|
|
|
if Current (Self.Current) /= Self.Index then
|
|
|
|
|
raise Cursor_Has_Moved;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
if Is_Null (Self.Current, Self.Column + Field) then
|
|
|
|
|
return Long_Long_Integer'First;
|
|
|
|
|
else
|
|
|
|
|
return Bigint_Value (Self.Current, Self.Column + Field);
|
|
|
|
|
end if;
|
|
|
|
|
end Bigint_Value;
|
|
|
|
|
|
|
|
|
|
-------------------
|
|
|
|
|
-- Boolean_Value --
|
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
|
|
function Boolean_Value
|
|
|
|
|
(Self : Orm_Element'Class; Field : Field_Index) return Boolean is
|
|
|
|
|
begin
|
|
|
|
|
if Current (Self.Current) /= Self.Index then
|
|
|
|
|
raise Cursor_Has_Moved;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
if Is_Null (Self.Current, Self.Column + Field) then
|
|
|
|
|
return False;
|
|
|
|
|
else
|
|
|
|
|
return Boolean_Value (Self.Current, Self.Column + Field);
|
|
|
|
|
end if;
|
|
|
|
|
end Boolean_Value;
|
|
|
|
|
|
|
|
|
|
-------------------
|
|
|
|
|
-- String_Value --
|
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
|
|
function String_Value
|
|
|
|
|
(Self : Orm_Element'Class; Field : Field_Index) return String is
|
|
|
|
|
begin
|
|
|
|
|
if Current (Self.Current) /= Self.Index then
|
|
|
|
|
raise Cursor_Has_Moved;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
if Is_Null (Self.Current, Self.Column + Field) then
|
|
|
|
|
return "";
|
|
|
|
|
else
|
|
|
|
|
return Value (Self.Current, Self.Column + Field);
|
|
|
|
|
end if;
|
|
|
|
|
end String_Value;
|
|
|
|
|
|
|
|
|
|
------------------
|
|
|
|
|
-- String_Value --
|
|
|
|
|
------------------
|
|
|
|
|
|
|
|
|
|
function String_Value
|
|
|
|
|
(Self : Orm_Element'Class; Field : Field_Index) return Unbounded_String is
|
|
|
|
|
begin
|
|
|
|
|
if Current (Self.Current) /= Self.Index then
|
|
|
|
|
raise Cursor_Has_Moved;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
if Is_Null (Self.Current, Self.Column + Field) then
|
|
|
|
|
return Null_Unbounded_String;
|
|
|
|
|
else
|
|
|
|
|
return Unbounded_Value (Self.Current, Self.Column + Field);
|
|
|
|
|
end if;
|
|
|
|
|
end String_Value;
|
|
|
|
|
|
|
|
|
|
----------------
|
|
|
|
|
-- Time_Value --
|
|
|
|
|
----------------
|
|
|
|
|
|
|
|
|
|
function Time_Value
|
|
|
|
|
(Self : Orm_Element'Class; Field : Field_Index) return Ada.Calendar.Time
|
|
|
|
|
is
|
|
|
|
|
begin
|
|
|
|
|
if Current (Self.Current) /= Self.Index then
|
|
|
|
|
raise Cursor_Has_Moved;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
if Is_Null (Self.Current, Self.Column + Field) then
|
|
|
|
|
return No_Time;
|
|
|
|
|
else
|
|
|
|
|
return Time_Value (Self.Current, Self.Column + Field);
|
|
|
|
|
end if;
|
|
|
|
|
end Time_Value;
|
|
|
|
|
|
|
|
|
|
-----------------
|
|
|
|
|
-- Float_Value --
|
|
|
|
|
------------------
|
|
|
|
|
|
|
|
|
|
function Float_Value
|
|
|
|
|
(Self : Orm_Element'Class; Field : Field_Index) return Float is
|
|
|
|
|
begin
|
|
|
|
|
if Current (Self.Current) /= Self.Index then
|
|
|
|
|
raise Cursor_Has_Moved;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
if Is_Null (Self.Current, Self.Column + Field) then
|
|
|
|
|
return Float'First;
|
|
|
|
|
else
|
|
|
|
|
return Float_Value (Self.Current, Self.Column + Field);
|
|
|
|
|
end if;
|
|
|
|
|
end Float_Value;
|
|
|
|
|
|
|
|
|
|
-----------------
|
|
|
|
|
-- Money_Value --
|
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
|
|
function Money_Value
|
|
|
|
|
(Self : Orm_Element'Class; Field : Field_Index)
|
|
|
|
|
return T_Money is
|
|
|
|
|
begin
|
|
|
|
|
if Current (Self.Current) /= Self.Index then
|
|
|
|
|
raise Cursor_Has_Moved;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
if Is_Null (Self.Current, Self.Column + Field) then
|
|
|
|
|
return T_Money'First;
|
|
|
|
|
else
|
|
|
|
|
return Money_Value (Self.Current, Self.Column + Field);
|
|
|
|
|
end if;
|
|
|
|
|
end Money_Value;
|
|
|
|
|
|
|
|
|
|
----------------------
|
|
|
|
|
-- Generic_Managers --
|
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
|
|
package body Generic_Managers is
|
|
|
|
|
|
|
|
|
|
function Internal_Element
|
|
|
|
|
(Self : Forward_Cursor'Class;
|
|
|
|
|
Column : Field_Index;
|
|
|
|
|
Data : Shared_List_Data;
|
|
|
|
|
Depth : Natural) return Element_Type;
|
|
|
|
|
pragma Inline (Internal_Element);
|
|
|
|
|
|
|
|
|
|
----------------------
|
|
|
|
|
-- Internal_Element --
|
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
|
|
function Internal_Element
|
|
|
|
|
(Self : Forward_Cursor'Class;
|
|
|
|
|
Column : Field_Index;
|
|
|
|
|
Data : Shared_List_Data;
|
|
|
|
|
Depth : Natural) return Element_Type
|
|
|
|
|
is
|
|
|
|
|
begin
|
|
|
|
|
return Result : Element_Type do
|
|
|
|
|
Result.Index := Current (Self);
|
|
|
|
|
Result.Column := Column;
|
|
|
|
|
Result.Depth := Depth;
|
|
|
|
|
Result.Data := Data;
|
|
|
|
|
Result.Current := Forward_Cursor (Self);
|
|
|
|
|
end return;
|
|
|
|
|
end Internal_Element;
|
|
|
|
|
|
|
|
|
|
----------------------
|
|
|
|
|
-- Internal_Element --
|
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
|
|
function Internal_Element
|
|
|
|
|
(Self : Orm_Element'Class;
|
|
|
|
|
Field : Field_Index) return Element_Type is
|
|
|
|
|
begin
|
|
|
|
|
return Internal_Element
|
|
|
|
|
(Self.Current, Self.Column + Field, Self.Data, Self.Depth - 1);
|
|
|
|
|
end Internal_Element;
|
|
|
|
|
|
|
|
|
|
-------------
|
|
|
|
|
-- Element --
|
|
|
|
|
-------------
|
|
|
|
|
|
|
|
|
|
function Element
|
|
|
|
|
(Self : List'Class) return Element_Type
|
|
|
|
|
is
|
|
|
|
|
Data : constant Shared_List_Data_Access := Get_Data (Self);
|
|
|
|
|
begin
|
|
|
|
|
Assert (Me, Data /= null, "No data stored in list of elements");
|
|
|
|
|
Assert
|
|
|
|
|
(Me, Data.Session /= No_Session, "Session from list was released");
|
|
|
|
|
return Internal_Element (Self, 0, Get_Data (Self).all, Self.Depth);
|
|
|
|
|
end Element;
|
|
|
|
|
|
|
|
|
|
-------------
|
|
|
|
|
-- Element --
|
|
|
|
|
-------------
|
|
|
|
|
|
|
|
|
|
function Element
|
|
|
|
|
(Self : Direct_List'Class) return Element_Type
|
|
|
|
|
is
|
|
|
|
|
begin
|
|
|
|
|
return Internal_Element (Self, 0, Get_Data (Self).all, Self.Depth);
|
|
|
|
|
end Element;
|
|
|
|
|
|
|
|
|
|
-----------------
|
|
|
|
|
-- Build_Query --
|
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
|
|
function Build_Query
|
|
|
|
|
(Self : Manager_Type'Class;
|
|
|
|
|
Override_Fields : SQL_Field_List := Empty_Field_List)
|
|
|
|
|
return SQL_Query
|
|
|
|
|
is
|
|
|
|
|
Q : SQL_Query;
|
|
|
|
|
F : SQL_Field_List;
|
|
|
|
|
T : SQL_Table_List;
|
|
|
|
|
C : SQL_Criteria := No_Criteria;
|
|
|
|
|
begin
|
|
|
|
|
Internal_Query (F, T, C, Self.Select_Related, Self.Follow_LJ);
|
|
|
|
|
if Override_Fields /= Empty_Field_List then
|
|
|
|
|
F := Override_Fields;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
Query (Self, Q, F, T, C);
|
|
|
|
|
return Q;
|
|
|
|
|
end Build_Query;
|
|
|
|
|
|
|
|
|
|
------------------
|
|
|
|
|
-- Build_Delete --
|
|
|
|
|
------------------
|
|
|
|
|
|
|
|
|
|
function Build_Delete (Self : Manager_Type'Class) return SQL_Query is
|
|
|
|
|
Q : SQL_Query;
|
|
|
|
|
F : SQL_Field_List;
|
|
|
|
|
T : SQL_Table_List;
|
|
|
|
|
C : SQL_Criteria := No_Criteria;
|
|
|
|
|
begin
|
|
|
|
|
Internal_Query
|
|
|
|
|
(Fields => F,
|
|
|
|
|
From => T,
|
|
|
|
|
Criteria => C,
|
|
|
|
|
PK_Only => True,
|
|
|
|
|
Depth => 0, -- Never select related
|
|
|
|
|
Follow_LJ => False);
|
|
|
|
|
|
|
|
|
|
Query (Self, Q, F, T, C);
|
|
|
|
|
Q := SQL_Delete
|
|
|
|
|
(From => Table_Type,
|
|
|
|
|
Where => SQL_In (Tuple (F), Q));
|
|
|
|
|
Auto_Complete (Q);
|
|
|
|
|
return Q;
|
|
|
|
|
end Build_Delete;
|
|
|
|
|
|
|
|
|
|
---------
|
|
|
|
|
-- Get --
|
|
|
|
|
---------
|
|
|
|
|
|
|
|
|
|
function Get
|
|
|
|
|
(Self : Manager'Class;
|
|
|
|
|
Session : Session_Type;
|
|
|
|
|
Params : SQL_Parameters := No_Parameters) return List
|
|
|
|
|
is
|
|
|
|
|
Result : List;
|
|
|
|
|
begin
|
|
|
|
|
Result.Data := (Session => Session, Follow_LJ => Self.Follow_LJ);
|
|
|
|
|
Result.Depth := Select_Related (Self);
|
|
|
|
|
|
|
|
|
|
if Session.Flush_Before_Query then
|
|
|
|
|
Session.Flush;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
Result.Fetch (Session.DB, Build_Query (Self), Params);
|
|
|
|
|
return Result;
|
|
|
|
|
end Get;
|
|
|
|
|
|
|
|
|
|
---------
|
|
|
|
|
-- Get --
|
|
|
|
|
---------
|
|
|
|
|
|
|
|
|
|
function Get
|
|
|
|
|
(Query : String;
|
|
|
|
|
Session : Session_Type;
|
|
|
|
|
Params : SQL_Parameters := No_Parameters;
|
|
|
|
|
Related : Related_Depth := 0;
|
|
|
|
|
Follow_LJ : Boolean := False) return List
|
|
|
|
|
is
|
|
|
|
|
Result : List;
|
|
|
|
|
begin
|
|
|
|
|
Result.Data := (Session => Session, Follow_LJ => Follow_LJ);
|
|
|
|
|
Result.Depth := Integer (Related);
|
|
|
|
|
|
|
|
|
|
if Session.Flush_Before_Query then
|
|
|
|
|
Session.Flush;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
Result.Fetch (Session.DB, Query, Params);
|
|
|
|
|
return Result;
|
|
|
|
|
end Get;
|
|
|
|
|
|
|
|
|
|
------------
|
|
|
|
|
-- Delete --
|
|
|
|
|
------------
|
|
|
|
|
|
|
|
|
|
procedure Delete (Self : Manager'Class; Session : Session_Type) is
|
|
|
|
|
begin
|
|
|
|
|
Execute (Session.DB, Build_Delete (Self));
|
|
|
|
|
end Delete;
|
|
|
|
|
|
|
|
|
|
-------------
|
|
|
|
|
-- Prepare --
|
|
|
|
|
-------------
|
|
|
|
|
|
|
|
|
|
function Prepare
|
|
|
|
|
(Self : Manager'Class;
|
|
|
|
|
Use_Cache : Boolean := False;
|
|
|
|
|
On_Server : Boolean := False;
|
|
|
|
|
Name : String := "") return ORM_Prepared_Statement
|
|
|
|
|
is
|
|
|
|
|
begin
|
|
|
|
|
return ORM_Prepared_Statement'
|
|
|
|
|
(Related => Related_Depth (Select_Related (Self)),
|
|
|
|
|
Follow_LJ => Self.Follow_LJ,
|
|
|
|
|
Stmt => Prepare
|
|
|
|
|
(Build_Query (Self),
|
|
|
|
|
Name => Name,
|
|
|
|
|
Use_Cache => Use_Cache,
|
|
|
|
|
On_Server => On_Server));
|
|
|
|
|
end Prepare;
|
|
|
|
|
|
|
|
|
|
----------------
|
|
|
|
|
-- Get_Direct --
|
|
|
|
|
----------------
|
|
|
|
|
|
|
|
|
|
function Get_Direct
|
|
|
|
|
(Self : Manager'Class;
|
|
|
|
|
Session : Session_Type;
|
|
|
|
|
Params : SQL_Parameters := No_Parameters) return Direct_List
|
|
|
|
|
is
|
|
|
|
|
Result : Direct_List;
|
|
|
|
|
begin
|
|
|
|
|
Result.Data := (Session => Session, Follow_LJ => Self.Follow_LJ);
|
|
|
|
|
Result.Depth := Select_Related (Self);
|
|
|
|
|
|
|
|
|
|
if Session.Flush_Before_Query then
|
|
|
|
|
Session.Flush;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
Result.Fetch (Session.DB, Build_Query (Self), Params => Params);
|
|
|
|
|
return Result;
|
|
|
|
|
end Get_Direct;
|
|
|
|
|
|
|
|
|
|
---------
|
|
|
|
|
-- Get --
|
|
|
|
|
---------
|
|
|
|
|
|
|
|
|
|
function Get
|
|
|
|
|
(Query : ORM_Prepared_Statement'Class;
|
|
|
|
|
Session : Session_Type;
|
|
|
|
|
Params : SQL_Parameters := No_Parameters) return List
|
|
|
|
|
is
|
|
|
|
|
Result : List;
|
|
|
|
|
begin
|
|
|
|
|
Result.Data := (Session => Session, Follow_LJ => Query.Follow_LJ);
|
|
|
|
|
Result.Depth := Integer (Query.Related);
|
|
|
|
|
|
|
|
|
|
if Session.Flush_Before_Query then
|
|
|
|
|
Session.Flush;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
Result.Fetch (Session.DB, Query.Stmt, Params);
|
|
|
|
|
return Result;
|
|
|
|
|
end Get;
|
|
|
|
|
|
|
|
|
|
----------------
|
|
|
|
|
-- Get_Direct --
|
|
|
|
|
----------------
|
|
|
|
|
|
|
|
|
|
function Get_Direct
|
|
|
|
|
(Query : ORM_Prepared_Statement'Class;
|
|
|
|
|
Session : Session_Type;
|
|
|
|
|
Params : SQL_Parameters := No_Parameters) return Direct_List
|
|
|
|
|
is
|
|
|
|
|
Result : Direct_List;
|
|
|
|
|
begin
|
|
|
|
|
Result.Data := (Session => Session, Follow_LJ => Query.Follow_LJ);
|
|
|
|
|
Result.Depth := Integer (Query.Related);
|
|
|
|
|
|
|
|
|
|
if Session.Flush_Before_Query then
|
|
|
|
|
Session.Flush;
|
|
|
|
|
end if;
|
|
|
|
|
|
|
|
|
|
Result.Fetch (Session.DB, Query.Stmt, Params => Params);
|
|
|
|
|
return Result;
|
|
|
|
|
end Get_Direct;
|
|
|
|
|
|
|
|
|
|
--------------
|
|
|
|
|
-- Distinct --
|
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
function Distinct (Self : Manager) return Manager
|
|
|
|
|
is
|
|
|
|
|
Result : Manager := Self;
|
|
|
|
|
begin
|
|
|
|
|
Distinct (Result);
|
|
|
|
|
return Result;
|
|
|
|
|
end Distinct;
|
|
|
|
|
|
|
|
|
|
------------
|
|
|
|
|
-- Filter --
|
|
|
|
|
------------
|
|
|
|
|
|
|
|
|
|
function Filter
|
|
|
|
|
(Self : Manager; Condition : SQL_Criteria) return Manager
|
|
|
|
|
is
|
|
|
|
|
Result : Manager;
|
|
|
|
|
begin
|
|
|
|
|
-- Bug in GNAT, maybe: "Result := Self" results in a corruption
|
|
|
|
|
-- in the reference counting of the criteria. The workaround is
|
|
|
|
|
-- to do an explicit copy.
|
|
|
|
|
Copy (Self, Into => Result);
|
|
|
|
|
Filter (Result, Condition);
|
|
|
|
|
return Result;
|
|
|
|
|
end Filter;
|
|
|
|
|
|
|
|
|
|
-----------
|
|
|
|
|
-- Limit --
|
|
|
|
|
-----------
|
|
|
|
|
|
|
|
|
|
function Limit
|
|
|
|
|
(Self : Manager;
|
|
|
|
|
Count : Natural;
|
|
|
|
|
From : Natural := 0) return Manager
|
|
|
|
|
is
|
|
|
|
|
Result : Manager := Self;
|
|
|
|
|
begin
|
|
|
|
|
Limit (Result, Count, From);
|
|
|
|
|
return Result;
|
|
|
|
|
end Limit;
|
|
|
|
|
|
|
|
|
|
--------------
|
|
|
|
|
-- Order_By --
|
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
function Order_By
|
|
|
|
|
(Self : Manager;
|
|
|
|
|
By : SQL_Field_List) return Manager
|
|
|
|
|
is
|
|
|
|
|
Result : Manager := Self;
|
|
|
|
|
begin
|
|
|
|
|
GNATCOLL.SQL.Orm.Order_By (Result, By);
|
|
|
|
|
return Result;
|
|
|
|
|
end Order_By;
|
|
|
|
|
|
|
|
|
|
--------------
|
|
|
|
|
-- Order_By --
|
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
function Order_By
|
|
|
|
|
(Self : Manager; By : SQL_Field'Class) return Manager
|
|
|
|
|
is
|
|
|
|
|
Result : Manager := Self;
|
|
|
|
|
begin
|
|
|
|
|
GNATCOLL.SQL.Orm.Order_By (Result, +By);
|
|
|
|
|
return Result;
|
|
|
|
|
end Order_By;
|
|
|
|
|
|
|
|
|
|
--------------------
|
|
|
|
|
-- Select_Related --
|
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
|
|
function Select_Related
|
|
|
|
|
(Self : Manager;
|
|
|
|
|
Depth : Related_Depth;
|
|
|
|
|
Follow_Left_Join : Boolean := False) return Manager
|
|
|
|
|
is
|
|
|
|
|
Result : Manager := Self;
|
|
|
|
|
begin
|
|
|
|
|
Select_Related (Result, Integer (Depth), Follow_Left_Join);
|
|
|
|
|
return Result;
|
|
|
|
|
end Select_Related;
|
|
|
|
|
|
|
|
|
|
end Generic_Managers;
|
|
|
|
|
|
|
|
|
|
end GNATCOLL.SQL.Orm.Impl;
|