You are not logged in.
Pages: 1
Thank you for reply.
Do you plan to support Windows in the future?
I cannot compile version downloaded from https://github.com/synopse/mORMot/tree/ … odeCleanup
[dcc32 Error] SpiderMonkey.pas(600): E2398 Class methods in record types must be static
[dcc32 Error] SpiderMonkey.pas(601): E2398 Class methods in record types must be static
[dcc32 Error] SpiderMonkey.pas(602): E2398 Class methods in record types must be static
[dcc32 Error] SpiderMonkey.pas(603): E2398 Class methods in record types must be static
[dcc32 Error] SpiderMonkey.pas(604): E2398 Class methods in record types must be static
[dcc32 Error] SpiderMonkey.pas(605): E2398 Class methods in record types must be static
[dcc32 Error] SpiderMonkey.pas(606): E2398 Class methods in record types must be static
[dcc32 Error] SpiderMonkey.pas(607): E2398 Class methods in record types must be static
[dcc32 Error] SpiderMonkey.pas(609): E2398 Class methods in record types must be static
[dcc32 Error] SpiderMonkey.pas(2026): E1030 Invalid compiler directive: 'external'
[dcc32 Error] SpiderMonkey.pas(2026): E2029 ',' or ':' expected but identifier 'name' found
[dcc32 Error] SpiderMonkey.pas(2028): E2070 Unknown directive: 'JS_DisableExtraThreads'
[dcc32 Error] SpiderMonkey.pas(2029): E2004 Identifier redeclared: 'external'
[dcc32 Error] SpiderMonkey.pas(2029): E2029 ',' or ':' expected but identifier 'name' found
[dcc32 Error] SpiderMonkey.pas(2043): E2029 Type expected but 'TYPE' found
[dcc32 Error] SpiderMonkey.pas(2044): E1030 Invalid compiler directive: 'external'
[dcc32 Error] SpiderMonkey.pas(2044): E2029 ',' or ':' expected but identifier 'name' found
[dcc32 Error] SpiderMonkey.pas(2047): E2029 Type expected but 'TYPE' found
[dcc32 Error] SpiderMonkey.pas(2048): E1030 Invalid compiler directive: 'external'
[dcc32 Error] SpiderMonkey.pas(2048): E2029 ',' or ':' expected but identifier 'name' found
[dcc32 Error] SpiderMonkey.pas(2051): E2029 Type expected but 'TYPE' found
[dcc32 Error] SpiderMonkey.pas(2052): E1030 Invalid compiler directive: 'external'
[dcc32 Error] SpiderMonkey.pas(2052): E2029 ',' or ':' expected but identifier 'name' found
[dcc32 Error] SpiderMonkey.pas(2055): E2029 Type expected but 'TYPE' found
[dcc32 Error] SpiderMonkey.pas(2056): E1030 Invalid compiler directive: 'external'
[dcc32 Error] SpiderMonkey.pas(2056): E2029 ',' or ':' expected but identifier 'name' found
[dcc32 Error] SpiderMonkey.pas(2060): E2029 Type expected but 'TYPE' found
[dcc32 Error] SpiderMonkey.pas(2061): E1030 Invalid compiler directive: 'external'
[dcc32 Error] SpiderMonkey.pas(2061): E2029 ',' or ':' expected but identifier 'name' found
[dcc32 Error] SpiderMonkey.pas(2065): E2029 Type expected but 'TYPE' found
[dcc32 Error] SpiderMonkey.pas(2066): E1030 Invalid compiler directive: 'external'
[dcc32 Error] SpiderMonkey.pas(2066): E2029 ',' or ':' expected but identifier 'name' found
[dcc32 Error] SpiderMonkey.pas(2069): E2029 Type expected but 'TYPE' found
[dcc32 Error] SpiderMonkey.pas(2072): E1030 Invalid compiler directive: 'external'
[dcc32 Error] SpiderMonkey.pas(2072): E2029 ',' or ':' expected but identifier 'name' found
[dcc32 Error] SpiderMonkey.pas(2074): E2029 Type expected but 'TYPE' found
[dcc32 Error] SpiderMonkey.pas(2075): E1030 Invalid compiler directive: 'external'
[dcc32 Error] SpiderMonkey.pas(2075): E2029 ',' or ':' expected but identifier 'name' found
[dcc32 Fatal Error] SpiderMonkey.pas(2075): E2226 Compilation terminated; too many errors
Should I use any compiler directive?
The same issue is posted here:
https://synopse.info/forum/viewtopic.php?id=5442
I need to connect to MSSQL server via ODBC but without creating a DSN. As stated in Microsoft documentation it is possible to set Connection String without DSN:
"[Provider=MSDASQL;] DRIVER=driver; SERVER=server;
DATABASE=database; UID=MyUserID; PWD=MyPassword"
http://msdn.microsoft.com/en-us/library … 85%29.aspx
But I haven'y any idea how to use TOleDBODBCSQLConnectionProperties constructor to achieve that. Itried to modify connection string by without result.
Kind Regards
According to my previuos topic https://synopse.info/forum/viewtopic.php?id=1131 I need an advice how to use nested and named transactions in TOleDBConnectionProperties
I've tried ThreadSafeConnection and I've got the same error.
I include my entire source code
program mormotTransactionsTest;
{$APPTYPE CONSOLE}
{$R *.res}
//SQL Script
{
CREATE TABLE TST_Document
(
documentId bigint not null identity(1,1) primary key,
documentDate datetime,
documentNo varchar(15)
)
GO
CREATE TABLE TST_DocumentItem
(
documentItemId bigint not null identity(1,1) primary key,
documentId bigint,
name nvarchar(200),
quantity numeric(12,3)
)
GO
CREATE PROCEDURE TST_SP_DOCUMENTS
AS
BEGIN
SET NOCOUNT ON;
declare
@CURRENDOCTS table(
id_document int
)
insert into @CURRENDOCTS select documentId from tst_document;
select * from @CURRENDOCTS;
END
}
uses
System.SysUtils,
System.Variants,
System.Classes,
SynCommons,
SynDB,
SynOleDB,
mORMot;
Type
TdocDao = class
class procedure SaveDocument(documentNo: string; documentDate: TDateTime) ;
class procedure SaveDocumentItem(documentId: integer; name: string; quantity: currency);
end;
var
Props: TOleDBConnectionProperties;
Model: TSQLModel;
class procedure TDocDao.SaveDocument(documentNo: string; documentDate: TDateTime);
var
query: rawUtf8;
dbStatement: ISQLDBStatement;
lastInsertedId: integer;
i: integer;
begin
try
Props.ThreadSafeConnection.StartTransaction;
query := 'insert into tst_document(documentNo, documentDate) values (?,?)';
dbStatement := Props.NewThreadSafeStatementPrepared(query, false);
dbStatement.BindVariant(1, 'DOC/1234', false);
dbStatement.BindDateTime(2, Now);
dbStatement.ExecutePrepared;
with Props.Execute('SELECT @@IDENTITY as ''Identity''', []) do
while Step do
begin
lastInsertedId := ColumnVariant(0);
end;
for i := 1 to 3 do
begin
SaveDocumentItem(lastInsertedId, 'Assort ' + IntToStr(i), i);
end;
Props.ThreadSafeConnection.Commit;
except
on e: Exception do
Props.ThreadSafeConnection.Rollback;
end;
end;
class procedure TDocDao.SaveDocumentItem(documentId: integer; name: string; quantity: currency);
var
isOuterTrans: boolean;
dbStatement : ISQLDBStatement;
query: rawUtf8;
begin
try
query := 'insert into tst_documentItem(documentId, name, quantity) values (?,?,?)';
dbStatement := Props.NewThreadSafeStatementPrepared(query, false);
isOuterTrans := Props.ThreadSafeConnection.InTransaction;
//I get here FALSE despite the fact that transaction is already opened (it was opened in procedure SaveDocument)
if not isOuterTrans then
Props.ThreadSafeConnection.StartTransaction;
dbStatement.Bind(1, documentId);
dbStatement.BindVariant(2, name, false);
dbStatement.BindVariant(3, quantity, false);
dbStatement.ExecutePrepared;
if not isOuterTrans then
Props.ThreadSafeConnection.Commit;
except
on e:Exception do
begin
if not isOuterTrans then
Props.ThreadSafeConnection.Rollback;
raise Exception.Create('Save DocumentItem Error ');
end;
end;
end;
procedure InitializeConnection;
begin
Props := TOleDBMSSQLConnectionProperties.Create('localhost', 'McspalPosNew', 'sp', 'sp');
end;
procedure TestRetrieveFromSP;
var
stmt: ISQLDBStatement;
begin
Writeln('Start TestRetrieveFromSP');
stmt := Props.NewThreadSafeStatementPrepared('exec TST_SP_DOCUMENTS', true);
stmt.ExecutePrepared;
//WITHOUT SET NOCOUNT ON step returns false and no row is fetched
while stmt.Step do
Writeln('fetch row...');
Writeln('End TestRetrieveFromSP');
end;
procedure TestTransaction;
begin
TdocDao.SaveDocument('DOC/1234', Now);
end;
begin
with TSQLLog.Family do begin
Level := LOG_VERBOSE;
HighResolutionTimeStamp := true;
AutoFlushTimeOut := 0;
ArchiveAfterDays := 1; // archive after one day
end;
InitializeConnection;
TestTransaction;
//TestRetrieveFromSP;
Readln;
end.
I faced two problems with TOleDBConnectionProperties :
1. Transaction:
When I open transaction in some procedure, method InTransaction returns false - but I think it shout be true.
Please look at following source code:
class procedure TDocDao.SaveDocument(documentNo: string; documentDate: TDateTime);
var
query: rawUtf8;
dbStatement: ISQLDBStatement;
lastInsertedId: integer;
i: integer;
begin
try
Props.MainConnection.StartTransaction;
query := 'insert into tst_document(documentNo, documentDate) values (?,?)';
dbStatement := Props.NewThreadSafeStatementPrepared(query, false);
dbStatement.BindVariant(1, 'DOC/1234', false);
dbStatement.BindDateTime(2, Now);
dbStatement.ExecutePrepared;
with Props.Execute('SELECT @@IDENTITY as ''Identity''', []) do
while Step do
begin
lastInsertedId := ColumnVariant(0);
end;
for i := 1 to 3 do
begin
SaveDocumentItem(lastInsertedId, 'Assort ' + IntToStr(i), i);
end;
Props.MainConnection.Commit; //here I get error because transaction was commited in SaveDocumentItem procedure
except
on e: Exception do
Props.MainConnection.Rollback;
end;
end;
class procedure TDocDao.SaveDocumentItem(documentId: integer; name: string; quantity: currency);
var
isOuterTrans: boolean;
dbStatement : ISQLDBStatement;
query: rawUtf8;
begin
try
query := 'insert into tst_documentItem(documentId, name, quantity) values (?,?,?)';
dbStatement := Props.NewThreadSafeStatementPrepared(query, false);
isOuterTrans := Props.MainConnection.InTransaction;
//I get here FALSE despite the fact that transaction is already opened (it was opened in procedure SaveDocument)
if not isOuterTrans then
Props.MainConnection.StartTransaction;
dbStatement.Bind(1, documentId);
dbStatement.BindVariant(2, name, false);
dbStatement.BindVariant(3, quantity, false);
dbStatement.ExecutePrepared;
if not isOuterTrans then
Props.MainConnection.Commit;
except
on e:Exception do
begin
if not isOuterTrans then
Props.MainConnection.Rollback;
raise Exception.Create('Save DocumentItem Error ');
end;
end;
end;
Am I doing something wrong?
My another question is if there is a way to use named transaction with TOleDBConnectionProperties ?
2. Fetch rows from stored procedure witch uses temprary table
When I want to fech rows from stored procedure whitch uses temporary table it's nessesary to set SET NOCOUNT ON, otherwise it is impossible to fetch rows (function step returns False ). When I have "normal" stored procedure without any temporary tables or computations SET NOCOUNT ON isn't reqired. Is it correct?
I inculde my entire source code.
program mormotTransactionsTest;
{$APPTYPE CONSOLE}
{$R *.res}
//SQL Script
{
CREATE TABLE TST_Document
(
documentId bigint not null identity(1,1) primary key,
documentDate datetime,
documentNo varchar(15)
)
GO
CREATE TABLE TST_DocumentItem
(
documentItemId bigint not null identity(1,1) primary key,
documentId bigint,
name nvarchar(200),
quantity numeric(12,3)
)
GO
CREATE PROCEDURE TST_SP_DOCUMENTS
AS
BEGIN
SET NOCOUNT ON;
declare
@CURRENDOCTS table(
id_document int
)
insert into @CURRENDOCTS select documentId from tst_document;
select * from @CURRENDOCTS;
END
}
uses
System.SysUtils,
System.Variants,
System.Classes,
SynCommons,
SynDB,
SynOleDB,
mORMot;
Type
TdocDao = class
class procedure SaveDocument(documentNo: string; documentDate: TDateTime) ;
class procedure SaveDocumentItem(documentId: integer; name: string; quantity: currency);
end;
var
Props: TOleDBConnectionProperties;
Model: TSQLModel;
class procedure TDocDao.SaveDocument(documentNo: string; documentDate: TDateTime);
var
query: rawUtf8;
dbStatement: ISQLDBStatement;
lastInsertedId: integer;
i: integer;
begin
try
Props.MainConnection.StartTransaction;
query := 'insert into tst_document(documentNo, documentDate) values (?,?)';
dbStatement := Props.NewThreadSafeStatementPrepared(query, false);
dbStatement.BindVariant(1, 'DOC/1234', false);
dbStatement.BindDateTime(2, Now);
dbStatement.ExecutePrepared;
with Props.Execute('SELECT @@IDENTITY as ''Identity''', []) do
while Step do
begin
lastInsertedId := ColumnVariant(0);
end;
for i := 1 to 3 do
begin
SaveDocumentItem(lastInsertedId, 'Assort ' + IntToStr(i), i);
end;
Props.MainConnection.Commit;//here I get error because transaction was commited in SaveDocumentItem procedure
except
on e: Exception do
Props.MainConnection.Rollback;
end;
end;
class procedure TDocDao.SaveDocumentItem(documentId: integer; name: string; quantity: currency);
var
isOuterTrans: boolean;
dbStatement : ISQLDBStatement;
query: rawUtf8;
begin
try
query := 'insert into tst_documentItem(documentId, name, quantity) values (?,?,?)';
dbStatement := Props.NewThreadSafeStatementPrepared(query, false);
isOuterTrans := Props.MainConnection.InTransaction;
//I get here FALSE despite the fact that transaction is already opened (it was opened in procedure SaveDocument)
if not isOuterTrans then
Props.MainConnection.StartTransaction;
dbStatement.Bind(1, documentId);
dbStatement.BindVariant(2, name, false);
dbStatement.BindVariant(3, quantity, false);
dbStatement.ExecutePrepared;
if not isOuterTrans then
Props.MainConnection.Commit;
except
on e:Exception do
begin
if not isOuterTrans then
Props.MainConnection.Rollback;
raise Exception.Create('Save DocumentItem Error ');
end;
end;
end;
procedure InitializeConnection;
begin
Props := TOleDBMSSQLConnectionProperties.Create('localhost', 'MyDb', 'sa', 'sa');
end;
procedure TestRetrieveFromSP;
var
stmt: ISQLDBStatement;
begin
Writeln('Start TestRetrieveFromSP');
stmt := Props.NewThreadSafeStatementPrepared('exec TST_SP_DOCUMENTS', true);
stmt.ExecutePrepared;
//WITHOUT SET NOCOUNT ON step returns false and no row is fetched
while stmt.Step do
Writeln('fetch row...');
Writeln('End TestRetrieveFromSP');
end;
procedure TestTransaction;
begin
TdocDao.SaveDocument('DOC/1234', Now);
end;
begin
with TSQLLog.Family do begin
Level := LOG_VERBOSE;
HighResolutionTimeStamp := true;
AutoFlushTimeOut := 0;
ArchiveAfterDays := 1; // archive after one day
end;
InitializeConnection;
TestTransaction;
TestRetrieveFromSP;
Readln;
end.
I need to write custom JSON Serializer. In this case I want to use Synopse RTTI instead of native Delphi RTTI. Is it possible to obtain public fields and properties with Synopse RTTI? I can't find any example for obtaining fields information. For obtaining properties I use following code:
CP := InternalClassProp(AClass);
if CP<>nil then begin
P := @CP^.PropList;
for i := 0 to CP^.PropCount-1 do
begin
LPropertyInfo.PropType := P^.PropType^.Name;
if P^.Index > 0 then
LPropertyInfo.PropLength := P^.Index
else
LPropertyInfo.PropLength := 0;
Result.Add(P^.Name, LPropertyInfo);
P := P^.Next;
end;
end;
Thank you. It works very well.
I need to have direct access to in-memory database and use TSQLDBSQLite3ConnectionProperties to access it.
I create my table and then insert data.
When I call
props.Execute( 'insert into Assortment(id, plu) values (222,222);', []);
no insert is executed. But
props.ExecuteNoResult( 'insert into Assortment(id, plu) values (?,?);', [111, 111])
works ok.
I also tried to insert data in loop:
dbStatement := props.NewThreadSafeStatementPrepared('insert into Assortment(id, plu) values (?,?);', false);
for I := 1 to 2 do
begin
dbStatement.Bind(1,i);
dbStatement.Bind(2, i+55);
dbStatement.ExecutePrepared;
end
First insert is ok, but second time I get error: 'library routine called out of sequence'; I have to call dbStatement.Prepare() but i don't understand why, maybe I do something wrong?
Here is my sample application
program InMemoryDB;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
mORMotSQLite3,
SynCommons,
SynDB,
synDBSqLite3,
mORMotHttpServer,
System.Actions,
synSqLite3;
var
Props: TSQLDBSQLite3ConnectionProperties;
dbStatement: TSQLDBStatement;
createQuery, fJsonBuffer: rawUTF8;
i: integer;
begin
try
createQuery := 'CREATE TABLE Assortment (ID integer primary key, plu integer);';
Props := TSQLDBSQLite3ConnectionProperties.Create(':memory:','','','');
props.ExecuteNoResult(createQuery, []);
props.ExecuteNoResult( 'insert into Assortment(id, plu) values (?,?);', [111, 111]); //ok
props.Execute( 'insert into Assortment(id, plu) values (222,222);', []); //
fJSONBuffer := props.Execute('Select id from Assortment', []).FetchAllAsJSON(true);
Writeln('Select 1: ' + fJsonBuffer);;
dbStatement := props.NewThreadSafeStatementPrepared('insert into Assortment(id, plu) values (?,?);', false);
for I := 1 to 2 do
begin
if i > 1 then
dbStatement.Prepare('insert into Assortment(id, plu) values (?,?)', false); // without this I get error 'library routine called out of sequence'
dbStatement.Bind(1,i);
dbStatement.Bind(2, i+55);
dbStatement.ExecutePrepared;
end;
fJSONBuffer := props.Execute('Select id from Assortment', []).FetchAllAsJSON(true);
Writeln('Select 2: ' + fJsonBuffer);;
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Pages: 1