-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathqdb.pas
11450 lines (10748 loc) · 328 KB
/
qdb.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
unit qdb;
interface
{$I 'qdac.inc'}
{
Todo:2015.7.16
=========
1.QDB 在字段列表太多时,效率会明显下降(五月光报告)
2.QDB
Changes:
2015.12.14
==========
* 修正了 SetRecNo 没有正确定位到指定位置的问题(蜗牛也是牛报告)
2015.12.7
==========
* 修正了 SetRecNo 时比较值时忘记加一的问题(tgwang报告)
+ 增加对设计器通过编辑字段设计表的支持(易度变和建议)
2015.12.6
==========
* 修正了与 2007 的兼容问题(蜗牛也是牛报告)
2015.11.14
==========
* 修正了使用表达式过滤时,TQFilterExp 析构时 FValue 没有清理造成的内存泄露(阿木报告)
2015.11.10
==========
* 修正了CopyFrom模式为dcmView和dcmFiltered时,如果数据是过滤过的数据时出错的问题(幽灵报告)
2015.10.21
==========
* 修正了OpenDataSet在脚本没返回结果集时未抛出错误的问题
2015.10.20
==========
* 修正了AddResultSet对多数据集支持时未修改FActiveFieldDefs造成出错的问题(不得闲报告)
* 修正了AddResultSet未检查当前结果集字段是否已有字段信息的问题
2015.10.15
===========
* 修正了CloneSourceEdit没有处理克隆的数据集内容编辑完成时,没有到过滤和排序进行处理的问题
* 修正了TQRecords.Delete删除时没有标记索引信息脏的问题
2015.10.13
==========
* 修正了 CopyFrom 时,如果设置了分页,且复制模式为dcmView时,复制的不是当前页内容的问题(幽灵报告)
2015.10.12
==========
* 修正了 ApplyChanges 合并变更内容时,未重置记录的 FChangedIndex 造成的问题(AK47报告)
2015.10.10
==========
* 将 TQSocketProvider 从 qprov_pgsql 移入此单元
+ 合并不得闲编写的 TQLibProvider
2015.9.10
=========
* 修正了克隆的数据集 Records 列表由于未指向原始结果集,造成访问可能存在问题(阿木报告)
* 修正了 SaveToStream 函数中,usUnmodified 错误的写成usModified的问题(阿木报告)
* 修正了连接数据库用CommandText+Open方法直接打开数据集出错时未抛出异常的问题;
* 修正了连接数据库直接提交时出现AV错误的问题
* 修正 Provider OpenDataSet 函数同步打开判定标志位错误的问题
2015.9.9
=========
* 修正了 TQDataSet 在克隆的数据集时过滤时出错的问题(阿木报告)
2015.9.1
=========
+ 支持先设置 Provider 和 CommandText 再调用 Open 打开数据集的方式(AK47、空、ijia建议)
2015.8.30
=========
* 修正了 InternalSetData 时AsTime对时间类型的处理错误(阿木报告)
2015.7.31
=========
* 修正了克隆的数据集编辑时出错的问题(阿木报告)
* 修正了将Owner为其它数据源的数据集加入到数据集列表后,退出时出错的问题(阿木报告)
2015.7.30
=========
* 修正了 CreateFieldsByUser 在使用 TFields.LifeCycle 时的判定算法错误(AK47报告)
2015.7.22
---------
* 修正了Blob数据无清正确清除的问题(感谢ijia报告)
}
uses classes, sysutils, types, RTLConsts, qstring, qrbtree, qdigest, qworker,
qsimplepool, db, fmtbcd, dbcommon, SqlTimSt, variants, syncobjs, dateutils,
qtimetypes, qvalue, qmacros
{$IFDEF MSWINDOWS},
windows, winsock
{$ELSE}
, Posix.Base, Posix.Stdio, Posix.Pthread, Posix.UniStd, System.IOUtils,
{$WARN UNIT_PLATFORM OFF}Posix.StrOpts, {$WARN UNIT_PLATFORM ON}
Posix.NetDB, Posix.SysSocket, Posix.NetinetIn, Posix.arpainet,
Posix.SysSelect,
Posix.Systime
{$ENDIF}
{$IFDEF UNICODE}
, Generics.Collections
{$ENDIF}
{$IF RTLVersion<22}// 2007-2010
, PerlRegEx, pcre
{$ELSE}
, RegularExpressionsCore
{$IFEND}
;
const
// 数据库架构对象定义
SCHEMA_DATABASE = $4000000; // 数据库
SCHEMA_SCHEMA = $20000000; // 元数据定义
SCHEMA_TABLE = $10000000; // 数据表
SCHEMA_COLUMN = $08000000; // 数据列
SCHEMA_TYPE = $04000000; // 数据类型
SCHEMA_METATYPE = $FF000000; // 元数据类型
// 数据列属性定义
SCHEMA_ISINDEX = $00000001; // 索引
SCHEMA_ISPRIMARY = $00000002; // 主键
SCHEMA_NULLABLE = $000000004; // 允许为空
SCHEMA_ISFIXED = $00000008; // 固定长度
SCHEMA_AUTOINC = $00000010; // 自动增加
SCHEMA_VISIBLE = $00000020; // 列是否可见
SCHEMA_READONLY = $00000040; // 列是否只读
SCHEMA_UNNAMED = $00000080; // 未命名列
SCHEMA_CALC = $00000100; // 内部计算列
SCHEMA_ARRAY = $00000200; // 数组类型
SCHEMA_INWHERE = $00000400; // 可在Where条件中使用,用于更新或删除数据
SCHEMA_UNIQUE = $00000800; // 唯一约束
SCHEMA_HASDEFAULT = $00001000; // 拥有默认值定义
SCHEMA_COLUMNATTR = $00001FFF; // 列属性掩码
// SQL数据类型(32位整数代表数据类型,高16位为掩码,低16位为类型编码)
SQL_MASK_COMPLEX = $80000000;
SQL_MASK_NUMERIC = $40000000; // 数值类型ID的掩码
SQL_MASK_FIXEDSIZE = $20000000; // 固定大小
SQL_MASK_INTEGER = SQL_MASK_NUMERIC OR SQL_MASK_FIXEDSIZE OR $10000000;
// 是一个整数类型
SQL_MASK_UNSIGNED = SQL_MASK_INTEGER OR $08000000; // 无符号类型
SQL_MASK_FLOAT = SQL_MASK_NUMERIC OR SQL_MASK_FIXEDSIZE; // 浮点数
SQL_MASK_SPEC = $04000000; // 是特定数据特有类型,如PostgreSQL的特定类型
SQL_MASK_ARRAY = $02000000; // 是数组的一部分
SQL_MASK_BINARY = $01000000; // 是二进制数据类型
SQL_MASK_AUTOINC = SQL_MASK_INTEGER OR $00800000; // 是自增的序列
SQL_MASK_CHAR = $00400000; // 字符
SQL_MASK_TIME = SQL_MASK_FIXEDSIZE OR $00200000; // 日期时间类型
SQL_MASK_LONGSIZE = $00100000; // 长长度类型
// 字符
SQL_BASE_CHAR = $00000001; // ANSI字符
SQL_BASE_WIDECHAR = $00000002; // Unicode字符
// 整数
SQL_BASE_BYTE = $00000003; // 单字节
SQL_BASE_WORD = $00000004; // 双字节
SQL_BASE_DWORD = $00000005; // 四字节
SQL_BASE_QWORD = $00000006; // 八字节
// 浮点数
SQL_BASE_SINGLE = $00000007; // 单精度浮点值
SQL_BASE_DOUBLE = $00000008; // 双精度浮点值
SQL_BASE_EXTENDED = $00000009; // 扩展浮点类型
SQL_BASE_BCD = $0000000A; // BCD类型
SQL_BASE_SMALLMONEY = $0000000B; // 短货币
SQL_BASE_MONEY = $0000000C; // 长货币
SQL_BASE_BOOLEAN = $0000000D; // 布尔
SQL_BASE_UUID = $0000000E; // UUID类型
SQL_BASE_BIT = $0000000F; // 位类型
// 日期时间
SQL_BASE_TIME = $00000010; // 时间类型
SQL_BASE_DATE = $00000011; // 日期类型
SQL_BASE_SMALLDATETIME = $00000012; // 短日期时间类型
SQL_BASE_DATETIME = $00000013; // 日期时间类型
SQL_BASE_INTERVAL = $00000014; // 时间间隔
SQL_BASE_TIMEOFFSET = $00000015; // 时间偏移
SQL_BASE_TIMESTAMP = $00000016; // 时间戳
SQL_BASE_BINARY = $00000017; // 二进制
// 扩展的类型
SQL_BASE_PICTURE = $00000018; // 图片(好吧,这个实际上仅早期的少数数据库支持,实际不会用到)
SQL_BASE_STREAM = $00000019; // 数据流
SQL_BASE_XML = $0000001A; // XML数据
SQL_BASE_JSON = $0000001B; // JSON数据
SQL_BASE_OID = $0000001C; // OID
SQL_BASE_POINT = $0000001D; // 点
SQL_BASE_LINE = $0000001E; // 线
SQL_BASE_LSEG = $0000001F; // 线段
SQL_BASE_BOX = $00000020; // 矩形
SQL_BASE_PATH = $00000021; // 路径
SQL_BASE_POLYGON = $00000022; // 多边形
SQL_BASE_CIRCLE = $00000023; // 圆
SQL_BASE_CIDR = $00000024; // 可以带掩码IP地址
SQL_BASE_INET = $00000025; // IP
SQL_BASE_MACADDR = $00000026; // 网卡物理地址
SQL_BASE_ROWS = $00000027; // 行集(记录集)
SQL_BASE_ACL = $00000028; // 访问控制列表
SQL_BASE_DATASET = $00000029; // 数据集
SQL_BASE_CURSOR = $0000002A; // 游标
SQL_BASE_VARIANT = $0000002B; // 变体
SQL_BASE_INTERFACE = $0000002C; // 接口
SQL_BASE_IDISPATCH = $0000002D; // IDispatch
SQL_BASE_OBJECT = $0000002E; // 对象
SQL_BASE_PARAMS = $0000002F; // 参数
SQL_BASE_CONNECTION = $00000030; // 连接
SQL_BASE_OLE = $00000031; // OLE对象,用OLESave和OLELoad保存和加载
SQL_BASE_POINTER = $00000032; // 指针引用
SQL_BASE_ENUM = $00000033; // 枚举
SQL_BASE_SET = $00000034; // 集合
SQL_BASE_TSVECTOR = $00000035; // 全文检索向量
SQL_BASE_TSQUERY = $00000036; // 全文检索查询
SQL_BASE_TREE = $00000037; // 树
SQL_BASE_ADT = $00000027; // 高级数据类型,用户在服务器端定义的数据类型
// 基本类型
SQL_UNKNOWN = $00000000; // 未知类型
// 整数类型
SQL_TINYINT = SQL_MASK_INTEGER OR SQL_BASE_BYTE; // -128-127
SQL_BYTE = SQL_TINYINT OR SQL_MASK_UNSIGNED; // 0-255
SQL_SMALLINT = SQL_MASK_INTEGER OR SQL_BASE_WORD; // 有符号的-32768-32767
SQL_WORD = SQL_SMALLINT OR SQL_MASK_UNSIGNED; // 无符号整数,0-65535
SQL_INTEGER = SQL_MASK_INTEGER OR SQL_BASE_DWORD; // 有符号的32位整数
SQL_DWORD = SQL_INTEGER OR SQL_MASK_UNSIGNED; // 无符号的32位整数
SQL_INT64 = SQL_MASK_INTEGER OR SQL_BASE_QWORD; // 有符号的64位整数
SQL_QWORD = SQL_INT64 OR SQL_MASK_UNSIGNED; // 无符号的64位整数
SQL_SMALLSERIAL = SQL_SMALLINT OR SQL_MASK_AUTOINC; // 16位自增
SQL_SERIAL = SQL_INTEGER OR SQL_MASK_AUTOINC; // 32位自增序列
SQL_BIGSERIAL = SQL_INT64 OR SQL_MASK_AUTOINC; // 64位自增序列
// 浮点类型
SQL_SINGLE = SQL_MASK_FLOAT OR SQL_BASE_DWORD OR SQL_BASE_SINGLE; // 有符号的32位实数
SQL_FLOAT = SQL_MASK_FLOAT OR SQL_BASE_QWORD OR SQL_BASE_DOUBLE; // 有符号的64位实数
SQL_BCD = SQL_MASK_FLOAT OR SQL_BASE_BCD; // 有符号的任意精度实数
SQL_NUMERIC = SQL_BCD;
SQL_MONEY = SQL_MASK_FLOAT OR SQL_BASE_MONEY; // 货币类型
SQL_SMALLMONEY = SQL_MASK_FLOAT OR SQL_BASE_SMALLMONEY; // 小货币类型
SQL_EXTENDED = SQL_MASK_FLOAT OR SQL_BASE_EXTENDED;
// 字符串类型
SQL_CHAR = SQL_MASK_FIXEDSIZE OR SQL_MASK_CHAR OR SQL_BASE_CHAR; // 固定长度字符串
SQL_VARCHAR = SQL_MASK_CHAR OR SQL_BASE_CHAR; // 变长字符串
SQL_WIDECHAR = SQL_MASK_FIXEDSIZE OR SQL_MASK_CHAR OR SQL_BASE_WIDECHAR;
// 固定长度Unicode字符串
SQL_WIDEVARCHAR = SQL_MASK_CHAR OR SQL_BASE_WIDECHAR; // 变长Unicode字符串
SQL_TEXT = SQL_VARCHAR OR SQL_MASK_LONGSIZE; // 文本
SQL_WIDETEXT = SQL_WIDEVARCHAR OR SQL_MASK_LONGSIZE; // Unicode文本
SQL_XML = SQL_WIDETEXT OR SQL_BASE_XML;
SQL_JSON = SQL_WIDETEXT OR SQL_BASE_JSON;
SQL_TREE = SQL_WIDETEXT OR SQL_BASE_TREE;
// 二进制数据类型
SQL_BINARY = SQL_MASK_FIXEDSIZE OR SQL_MASK_BINARY;
// 二进制数据
SQL_BYTES = SQL_BINARY or SQL_BASE_BINARY;
SQL_BIT = SQL_MASK_FIXEDSIZE OR SQL_BASE_BIT OR SQL_MASK_BINARY;
SQL_VARBIT = SQL_BASE_BIT OR SQL_MASK_BINARY;
SQL_VARBINARY = SQL_MASK_BINARY or SQL_BASE_BINARY; // 变长二进制数据
SQL_VARBYTES = SQL_VARBINARY;
SQL_LARGEOBJECT = SQL_VARBINARY OR SQL_MASK_LONGSIZE; // 大二进制对象(BLOB)
SQL_PICTURE = SQL_LARGEOBJECT OR SQL_BASE_PICTURE; // 图片数据
SQL_STREAM = SQL_LARGEOBJECT OR SQL_BASE_STREAM; // 流对象
SQL_OLE = SQL_LARGEOBJECT OR SQL_BASE_OLE;
SQL_BOOLEAN = SQL_MASK_FIXEDSIZE OR SQL_BASE_BOOLEAN; // 布尔
SQL_UUID = SQL_MASK_FIXEDSIZE OR SQL_BASE_UUID;
SQL_GUID = SQL_UUID;
SQL_BITS = SQL_BIT;
SQL_VARBITS = SQL_BASE_BIT;
// 日期时间类型
SQL_DATE = SQL_MASK_TIME OR SQL_BASE_DATE; // 日期
SQL_TIME = SQL_MASK_TIME OR SQL_BASE_TIME; // 时间
SQL_SMALLDATETIME = SQL_MASK_TIME or SQL_BASE_SMALLDATETIME; // 小日期时间类型
SQL_DATETIME = SQL_MASK_TIME OR SQL_BASE_DATETIME; // 日期时间
SQL_TIMESTAMP = SQL_MASK_TIME OR SQL_BASE_TIMESTAMP; // 时间戳
SQL_INTERVAL = SQL_MASK_TIME OR SQL_BASE_INTERVAL; // 时间间隔
SQL_TIMEOFFSET = SQL_MASK_TIME OR SQL_BASE_TIMEOFFSET; // 时间偏移
SQL_DATASET = SQL_MASK_COMPLEX OR SQL_BASE_DATASET; // 数据集
SQL_CURSOR = SQL_MASK_COMPLEX OR SQL_BASE_CURSOR; // 游标
SQL_VARIANT = SQL_MASK_COMPLEX OR SQL_BASE_VARIANT; // 变体
SQL_INTERFACE = SQL_MASK_COMPLEX OR SQL_BASE_INTERFACE; // 接口
SQL_IDISPATCH = SQL_MASK_COMPLEX OR SQL_BASE_IDISPATCH; // IDispatch
SQL_OBJECT = SQL_MASK_COMPLEX OR SQL_BASE_OBJECT; // 对象
SQL_PARAMS = SQL_MASK_COMPLEX OR SQL_BASE_PARAMS; // 参数
SQL_CONNECTION = SQL_MASK_COMPLEX OR SQL_BASE_CONNECTION; // 连接
SQL_REFERENCE = SQL_MASK_COMPLEX OR SQL_BASE_POINTER; // 指针引用,这种类型仅在运行时有效
SQL_ARRAY = SQL_MASK_COMPLEX OR SQL_MASK_ARRAY; // 数组
SQL_ADT = SQL_MASK_COMPLEX OR SQL_MASK_ARRAY OR SQL_BASE_ADT; // 高级数据类型
// PostgreSQL类型
SQL_PG_OID = SQL_MASK_SPEC OR SQL_DWORD OR SQL_MASK_AUTOINC OR SQL_BASE_OID;
SQL_PG_POINT = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_BASE_POINT;
SQL_PG_LINE = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_BASE_LINE;
SQL_PG_LSEG = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_BASE_LSEG;
SQL_PG_BOX = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_BASE_BOX;
SQL_PG_PATH = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_BASE_PATH;
SQL_PG_POLYGON = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_BASE_POLYGON;
SQL_PG_CIRCLE = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_BASE_CIRCLE;
SQL_PG_CIDR = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_BASE_CIDR;
SQL_PG_INET = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_BASE_INET;
SQL_PG_MACADDR = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_BASE_MACADDR;
SQL_PG_ROWS = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_BASE_ROWS;
SQL_PG_ACL = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_BASE_ACL;
SQL_PG_ENUM = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_BASE_ENUM;
SQL_PG_TSVECTOR = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_MASK_CHAR OR
SQL_BASE_TSVECTOR;
SQL_PG_TSQUERY = SQL_MASK_SPEC OR SQL_MASK_COMPLEX OR SQL_MASK_CHAR OR
SQL_BASE_TSQUERY;
// 已知错误代码
PROV_ERROR_SQL_EMPTY = $80000001; // 脚本为空
PROV_EEROR_RESULT_EMPTY = $80000002; // 结果集为空
PROV_DRIVER_NOT_FOUND = $80000003; // 驱动程序对应的动态链接库未找到
PROV_NOT_CONNECTED = $80000004; // 连接未就绪
// Provider标志位
PF_CONNECTING = $00000001; // 正在连接数据库
PF_CONNECTED = $00000002; // 已经连接到数据库
PF_CLOSING = $00000004; // 正在关闭连接
PF_CLOSED = $00000008; // 连接已经关闭
PF_EXECUTING = $00000010; // 连接正在执行脚本
PF_KEEPALIVE = $00000020; // 需要进行连接保持测试
PF_PEEKING = $00000040; // 正在执行连接保持测试
PF_NSLOOKUP = $00000080; // 正在解析服务器地址
PF_HANDSHAKE = $00000100; // 正在初始化握手
PF_LOGIN = $00000200; // 正在登录
{$IFDEF POSIX}
SOCKET_ERROR = -1;
{$ENDIF}
{$HPPEMIT '#pragma link "qdb"'}
type
{$IF RTLVersion<260}
PDateTimeRec = ^TDateTimeRec;
{$IFEND}
TQFieldDef = class;
TQFieldDefs = class;
TQSchema = class;
TQSchemas = class;
PQDataSet = ^TQDataSet;
TQDataSet = class;
TQProvider = class;
TQConverter = class;
TQConverterClass = class of TQConverter;
TQLocalCheck = class; // TCheckConstraint,TParams.ParseSQL解析SQL脚本
TQLocalChecks = class;
TQRecord = class;
TQFilterExp = class;
{$IFDEF UNICODE}
TQFieldDefList = TList<TQFieldDef>;
TQSchemaList = TList<TQSchema>;
TQDataSetList = TList<TQDataSet>;
TQFilterExps = TList<TQFilterExp>;
{$ELSE}
TQFieldDefList = TList;
TQSchemaList = TList;
TQDataSetList = TList;
TQFilterExps = TList;
{$ENDIF}
TQSDatabase = class;
TQSTable = class;
TQSColumn = class;
{ 排序表达式内部结构定义 }
PQSortExp = ^TQSortExp;
{ 编译后的排序表达式 }
TQSortExp = record
Field: TQFieldDef; // 排序的字段索引
OnCompare: TQValueCompare;
{ 是否降序排列 }
{ 是否忽略大小写 }
Desc, IgnoreCase: Boolean; // 是否降序排列
Next: PQSortExp; { 下一条件 }
end;
// 条件过滤表达式的处理
PQFilterExp = ^TQFilterExp;
{ 过滤条件支持的比较操作符
foUnknown : 未知
foEQ : 等于
foLT : 小于
foGT : 大于
foLE : 小于等于
foGE : 大于等于
foNotEQ : 不等于
foIn : 位于多个值列表之中
foNotIn : 值不存在于指定的列表中
foIsNull : 用于判断是否为空
foIsNotNull : 用于判断是否为非空
foLike : 包含,Like操作将被实际转换成foStartWith,foEndWith,foContains
foNotLike : 不包含
foStartWith : 以指定的字符串开始
foEndWith : 以指定的字符串结束
foContains : 包含
foRegex : 正则表达式匹配 }
TQFilterOperator = (foUnknown, foEQ, foLT, foGT, foLE, foGE, foNotEQ, foIn,
foNotIn, foIsNull, foIsNotNull, foLike, foNotLike, foStartWith, foEndWith,
foContains, foRegex);
{ 过滤操作时表达式之间的逻辑关系,内部使用
fgoUnknown : 未知
fgoAnd : 并且
fgoOr : 或者
fgoDone : 已完成,没有后续的逻辑关系了 }
TQFilterGroupOperator = (fgoUnknown, fgoAnd, fgoOr, fgoDone);
{ 过滤条件表达式 }
TQFilterExp = class
protected
FField: TQFieldDef; // 字段索引
FValue: TQValue; // 比较的目标值
FDisplayFormat: QStringW; // 字段的显示格式
FCompareOpr: TQFilterOperator; // 比较操作符
FOnCompare: TQValueCompare;
FNextOpr: TQFilterGroupOperator; // 下一逻辑表达式,最后一个表达式为fgoDone
FParent: TQFilterExp; // 父表达式
FItems: TQFilterExps; // 子表达式列表
FRegex: TPerlRegEx;
FDataSet: TQDataSet;
FLocker: TCriticalSection;
function GetCount: Integer;
function GetItems(AIndex: Integer): TQFilterExp;
procedure SetCompareOpr(const Value: TQFilterOperator);
public
constructor Create(ADataSet: TQDataSet); overload;
destructor Destroy; override;
function Add(AExp: TQFilterExp): Integer; overload; // 添加一个子表达式
function Add: TQFilterExp; overload; // 添加一个子表达式
procedure Clear; // 清除子表达式
procedure Parse(const S: QStringW);
property Count: Integer read GetCount; // 子表达式数据
property Items[AIndex: Integer]: TQFilterExp read GetItems; // 子表达式列表
property Value: TQValue read FValue; // 比较的目标值
function Accept(ARecord: TQRecord; AFilterOptions: TFilterOptions): Boolean;
property CompareOpr: TQFilterOperator read FCompareOpr write SetCompareOpr;
// 比较操作符
property NextOpr: TQFilterGroupOperator read FNextOpr write FNextOpr;
// 下一逻辑操作符
property Parent: TQFilterExp read FParent; // 父表达式
property Field: TQFieldDef read FField write FField; // 关联字段
end;
TQColumnValue = record
OldValue: TQValue;
NewValue: TQValue;
Changed: Boolean;
function CurrentValue: PQValue;
end;
PQColumnValue = ^TQColumnValue;
TQColumnValues = array of TQColumnValue;
// TQRecord 用于对应单条记录
TQRecord = class
private
FOriginIndex: Integer; // 在克隆时原始数据集中的索引
FChangedIndex: Integer; // 变更列表中的记录索引
FSortedIndex: Integer; // 当前排序结果中的记录索引
FFilteredIndex: Integer; // 当前过滤结果中的记录索引
{$IFNDEF AUTOREFCOUNT}
FRefCount: Integer; // 引用计数
{$ENDIF}
FBookmark: Pointer; // 记录对应的书签,指向记录自己
FBookmarkFlag: TBookmarkFlag; // 书签标志位
FStatus: TUpdateStatus; // 记录状态
FOwner: TComponent; // 记录所有者
FValues: TQColumnValues; // 值列表
FFields: TQFieldDefs; // 字段定义
FTag: Pointer; // 附加额外的标签数据
procedure ClearValues;
procedure Assign(ASource: TQRecord);
procedure CopyValues(const ASource: TQRecord);
function GetModified: Boolean;
public
constructor Create(AFields: TQFieldDefs); overload;
destructor Destroy; override;
procedure AddRef;
procedure Release;
{$IFDEF AUTOREFCOUNT}
function __ObjAddRef: Integer; override;
function __ObjRelease: Integer; override;
{$ENDIF}
procedure Reset;
property Modified: Boolean read GetModified;
property Owner: TComponent read FOwner;
property OriginIndex: Integer read FOriginIndex; // 在克隆时原始数据集中的索引
property ChangedIndex: Integer read FChangedIndex; // 当前数据集中的记录索引
property SortedIndex: Integer read FSortedIndex; // 当前排序结果中的记录索引
property FilteredIndex: Integer read FFilteredIndex; // 当前过滤结果中的记录索引
property RefCount: Integer read FRefCount; // 引用计数
property Bookmark: Pointer read FBookmark; // 记录对应的书签,指向记录自己
property BookmarkFlag: TBookmarkFlag read FBookmarkFlag; //
property Values: TQColumnValues read FValues; // 记录值列表
property Status: TUpdateStatus read FStatus write FStatus; // 记录状态
property Fields: TQFieldDefs read FFields;
end;
PQRecord = ^TQRecord;
/// <summary>支持的迭代器级别
/// rilForwardOnly : 只进迭代器,仅支持 First 和 Next 操作
/// rilBackwardOnly : 只退迭代器,仅支持 Last 和 Prior 操作
/// rilBidirection : 双向迭代器,支持 First/Last/Prior/Next 操作
/// riRandom : 随机迭代器,支持First/Last/Next/Prior/MoveTo 操作
TQRecordIteratorLevel = (rilForwardOnly, rilBackwardOnly, rilBidirection,
rilRandom);
/// <summary> TQRecords 接口用于实现一个记录集,TQDataSet、TQConverter 者实现了该
/// 接口,以便能够实现对数据的遍历
IQRecords = interface
function LoadFields(ADefs: TQFieldDefs): Boolean;
function GetRecordCount: Integer; // 获取记录总数
procedure First; // 到第一条记录
procedure Last; // 到最后一条记录
procedure Next; // 下一条记录
procedure Prior; // 前一条记录
procedure MoveTo(const AIndex: Cardinal); // 移动到指定的记录
function ActiveRecordBuffer: TQRecord; // 当前记录缓冲区
function AllocRecord: TQRecord; // 分配一个新的记录
procedure FreeRecord(ARec: TQRecord); // 释放一个记录
procedure AddRecord(ARec: TQRecord; Append: Boolean);
function GetIteratorType: TQRecordIteratorLevel; // 支持的迭代级别
procedure GetFieldValue(ARecord: PQRecord; AField: TField;
var AValue: TQValue);
procedure SetFieldValue(ARecord: PQRecord; AField: TField;
const AValue: TQValue);
end;
TQDirtyIndexType = (ditOrigin, ditChanged, ditSorted, ditFiltered);
TQRecords = class
protected
FFirstDirtyIndex: Integer;
FIndexType: TQDirtyIndexType;
FItems: TQPagedList;
function GetRecords(AIndex: Integer): TQRecord; inline;
procedure SetRecords(AIndex: Integer; const Value: TQRecord);
procedure ValidIndex(const AIndex: Integer);
function GetCount: Integer; inline;
public
constructor Create(AIndexType: TQDirtyIndexType); overload;
destructor Destroy; override;
procedure Assign(ASource: TQRecords);
procedure Clean;
function Add(const Value: TQRecord): Integer;
function AddWithoutRef(const Value: TQRecord): Integer;
procedure Delete(AIndex: Integer);
procedure DeleteWithoutRef(AIndex: Integer);
procedure Clear(ADoPack: Boolean = True);
procedure Insert(Index: Integer; const Value: TQRecord);
procedure MoveTo(AFrom, ATo: Integer);
procedure Unlink;
property Records[AIndex: Integer]: TQRecord read GetRecords
write SetRecords; default;
property Count: Integer read GetCount;
end;
TQFieldDef = class(TFieldDef)
private
FSchema: QStringW; // 架构名,如public
FDatabase: QStringW; // 数据库名
FTable: QStringW; // 表名
FBaseName: QStringW; // 数据表中原始的列名
FDBType: Integer; // 数据字段类型
FFlags: Integer; // 标志位
FValueType: TQValueDataType;
FDBNo: Word; // 数据库中原始字段序列号
FOnCompare: TQValueCompare; // 字段值的比较方法
{$IF RTLVersion>=24}
[Weak]
{$IFEND <=XE3}
FField: TField; // 关联的字段
FScale: Word;
function GetFlags(const Index: Integer): Boolean;
function GetIsArray: Boolean;
function GetItems(AIndex: Integer): TQFieldDef;
procedure SetDBType(const Value: Integer);
procedure SetField(const Value: TField);
procedure SetFlags(const Index: Integer; const Value: Boolean);
procedure SetScale(const Value: Word);
function GetCount: Integer;
function GetInternalFlags: Integer;
function GetReadOnly: Boolean;
procedure SetReadOnly(const Value: Boolean);
function GetVisible: Boolean;
procedure SetVisible(const Value: Boolean);
function GetNullable: Boolean;
procedure SetNullable(const Value: Boolean);
function GetFixed: Boolean;
procedure SetFixed(const Value: Boolean);
function GetValueType: TQValueDataType;
function GetOnCompare: TQValueCompare;
function GetIsBlob: Boolean;
function GetIsBinary: Boolean;
function GetInWhere(const Index: Integer): Boolean;
function GetDBType: Integer;
procedure SetInternalFlags(const Value: Integer);
procedure SetIsArray(const Value: Boolean);
protected
procedure LookupValueType;
public
constructor Create(Owner: TFieldDefs; const Name:
{$IFDEF UNICODE}string{$ELSE}WideString{$ENDIF}; DataType: TFieldType;
Size: Integer; Required: Boolean; FieldNo: Integer);
{$IFDEF UNICODE }override; {$ELSE}overload; {$ENDIF}
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
property Items[AIndex: Integer]: TQFieldDef read GetItems; default;
// 下面的属性对于非本单元来说是只读的
property Schema: QStringW read FSchema write FSchema;
property Database: QStringW read FDatabase write FDatabase;
property Table: QStringW read FTable write FTable;
property BaseName: QStringW read FBaseName write FBaseName;
property DBType: Integer read GetDBType write SetDBType;
property Field: TField read FField write SetField;
property Scale: Word read FScale write SetScale;
property DBNo: Word read FDBNo write FDBNo;
property IsPrimary: Boolean index SCHEMA_ISPRIMARY read GetFlags
write SetFlags;
property IsIndex: Boolean index SCHEMA_ISINDEX read GetFlags write SetFlags;
property IsUnique: Boolean index SCHEMA_UNIQUE read GetFlags write SetFlags;
property Nullable: Boolean read GetNullable write SetNullable;
property IsFixed: Boolean read GetFixed write SetFixed;
property IsAutoInc: Boolean index SCHEMA_AUTOINC read GetFlags
write SetFlags;
property Visible: Boolean read GetVisible write SetVisible;
property ReadOnly: Boolean read GetReadOnly write SetReadOnly;
property IsCalc: Boolean index SCHEMA_CALC read GetFlags write SetFlags;
property InWhere: Boolean index SCHEMA_INWHERE read GetInWhere
write SetFlags;
property IsArray: Boolean read GetIsArray write SetIsArray;
property HasDefault: Boolean index SCHEMA_HASDEFAULT read GetFlags
write SetFlags;
property IsBlob: Boolean read GetIsBlob;
property IsBinary: Boolean read GetIsBinary;
property Flags: Integer read GetInternalFlags write SetInternalFlags;
property Count: Integer read GetCount;
property ValueType: TQValueDataType read GetValueType;
property ValueComparor: TQValueCompare read GetOnCompare;
end;
TQFieldDefArray = array of TQFieldDef;
TQFieldDefs = class(TFieldDefs)
protected
procedure Notify(Item: TCollectionItem;
Action: classes.TCollectionNotification); override;
{$IFDEF UNICODE}
function GetFieldDefClass: TFieldDefClass; override;
{$ENDIF}
public
constructor Create(AOwner: TPersistent); {$IFDEF UNICODE}override; {$ENDIF}
end;
TQIntervalField = class(TField)
protected
{$IF RTLVersion>=24}
FIOBuffer: TValueBuffer;
{$IFEND}
function GetValue(var AValue: TQInterval): Boolean;
procedure SetValue(const AValue: TQInterval);
function GetAsInterval: TQInterval;
procedure SetAsInterval(AValue: TQInterval);
function GetClassDesc: string; override;
function GetAsString: String; override;
procedure SetAsString(const AValue: String); override;
function GetAsVariant: Variant; override;
procedure SetVarValue(const AValue: Variant); override;
procedure SetSize(Value: Integer); override;
public
constructor Create(AOwner: TComponent); override;
property AsInterval: TQInterval read GetAsInterval write SetAsInterval;
end;
TQRecordCheckEvent = procedure(ADataSet: TQDataSet; ACheck: TQLocalCheck;
var Accept: Boolean) of object;
TQRecordCheckConflictEvent = procedure(ADataSet: TQDataSet;
ACheck: TQLocalCheck; var AHandled: Boolean) of object;
/// <summary>
/// lctUnique - 唯一约束,Expression中指定的字段列表值的组合,在当前数据集中必需唯一
/// lctDefault - 默认值约束,Expression中指定的值为表达式默认值
/// lctRangeCheck - 范围约束,Expression中指定的表达式为值边界检查
/// </summary>
TQLocalCheckType = (lctUnique, lctDefault, lctRangeCheck);
TQLocalCheck = class(TCollectionItem)
// protected
// FNameHash: Cardinal;
// FOnCheck: TQRecordCheckEvent;
// FOnConflict: TQRecordCheckConflictEvent;
// FCheckExp: TQFilterExp;
// FValueHashes: TQHashTable;
// FName: QStringW;
// FExpr: QStringW;
// FErrorText: QStringW;
// FEnabled: Boolean;
// FCheckType: TQLocalCheckType;
// procedure SetName(const Value: QStringW);
// procedure SetEnabled(const Value: Boolean);
// procedure SetErrorText(const Value: QStringW);
// procedure SetExpr(const Value: QStringW);
// procedure SetOnCheck(const Value: TQRecordCheckEvent);
// procedure SetOnConflict(const Value: TQRecordCheckConflictEvent);
// procedure SetCheckType(const Value: TQLocalCheckType);
// function CheckRange: Boolean;
// function CheckUnique: Boolean;
// function CheckDefault: Boolean;
// function ParseDefault: Boolean;
// function ParseUnique: Boolean;
// function ParseCheck: Boolean;
// public
// destructor Destroy; override;
// // 执行默认的约束,如果失败返回False,如果成功,返回True
// function DefaultCheck: Boolean;
// procedure Assign(Source: TPersistent); override;
// function GetDisplayName: string; override;
// published
// /// <summary>名称</summary>
// property Name: QStringW read FName write SetName;
// /// <summary>约束表达式,详细说明:http://www.qdac.cc/?p=638</summary>
// property Expression: QStringW read FExpr write SetExpr;
// /// <summary>错误提示文本</summary>
// /// <remarks>错误提示中可以引用标志符,[Name]为约束名称,[Value]为违反约束的值</remarks>
// property ErrorText: QStringW read FErrorText write SetErrorText;
// /// <summary>是否启用本约束规则</summary>
// property Enabled: Boolean read FEnabled write SetEnabled;
// /// <summary>用户自定义的约束检查事件,优先于Expression检查</summary>
// property OnCheck: TQRecordCheckEvent read FOnCheck write SetOnCheck;
// /// <summary>在发生违反约束时,如何处理</summary>
// property OnConflict: TQRecordCheckConflictEvent read FOnConflict
// write SetOnConflict;
// /// <summary>约束类型</summary>
// property CheckType: TQLocalCheckType read FCheckType write SetCheckType;
end;
TQLocalChecks = class(TCollection)
protected
FDataSet: TQDataSet;
// FOnUpdate: TNotifyEvent;
// function GetItems(Index: Integer): TQLocalCheck;
// procedure SetItems(Index: Integer; const Value: TQLocalCheck);
public
// constructor Create(AOwner: TQDataSet); overload;
// function Add: TQLocalCheck; overload;
// function Find(const Name: QStringW): TQLocalCheck;
function Accept(ABuf: TQRecord): Boolean;
procedure Check(ABuf: TQRecord);
// procedure Update; reintroduce;
// property Items[Index: Integer]: TQLocalCheck read GetItems
// write SetItems; default;
// property OnUpdate: TNotifyEvent read FOnUpdate write FOnUpdate;
// property DataSet: TQDataSet read FDataSet;
end;
TQConvertStep = (csBeforeImport, csBeginImport, csLoadFields, csLoadData,
csEndImport, csAfterImport, csBeforeExport, csBeginExport, csSaveFields,
csSaveData, csEndExport, csAfterExport);
TQDataConveterProgress = procedure(ASender: TQConverter; AStep: TQConvertStep;
AProgress, ATotal: Integer) of object;
/// <summary>
/// 导出范围选项
/// </summary>
/// <list>
/// <item><term>merMeta</term><description>元数据(也就是字段定义)</description></item>
/// <item><term>merUnmodified</term><description>未修改的数据</description></item>
/// <item><term>merInserted</term><description>新插入的数据</description></item>
/// <item><term>merModified</term><description>已变更的数据</description></item>
/// <item><term>merDeleted</term><description>已删除的数据</description></item>
/// </list>
/// <remarks>
///
/// </remarks>
TQExportRange = (merMeta, merUnmodified, merInserted, merModified,
merDeleted);
TQRecordEnumProc = procedure(ASender: TComponent; AIndex: Integer;
ARecord: TQRecord; AParam: Pointer) of object;
{$IFDEF UNICODE}
TQRecordEnumProcA = reference to procedure(ASender: TComponent;
AIndex: Integer; ARecord: TQRecord);
{$ENDIF}
TQExportRanges = set of TQExportRange;
TQStreamProcessor = class(TComponent)
protected
procedure BeforeSave(ASourceStream: TStream; ATargetStream: TStream);
virtual; abstract;
procedure BeforeLoad(ASourceStream: TStream; ATargetStream: TStream);
virtual; abstract;
end;
TQStreamProcessorItem = class(TCollectionItem)
private
FProcessor: TQStreamProcessor;
published
property Processor: TQStreamProcessor read FProcessor write FProcessor;
end;
TQStreamProcessors = class(TCollection)
private
function GetProcessor(Index: Integer): TQStreamProcessorItem;
procedure SetProcessor(Index: Integer; const Value: TQStreamProcessorItem);
public
constructor Create; overload;
function Add: TQStreamProcessorItem; reintroduce;
property Items[Index: Integer]: TQStreamProcessorItem read GetProcessor
write SetProcessor; default;
end;
TQConverter = class(TComponent)
private
protected
FDataSet: TQDataSet;
FExportRanges: TQExportRanges;
FStream: TStream;
FOriginStream: TStream;
FDataSetCount: Integer;
FActiveDataSet: Integer;
FOnProgress: TQDataConveterProgress;
FStreamProcessors: TQStreamProcessors;
FStartOffset: Int64;
procedure SetDataSet(const Value: TQDataSet);
// 导出接口
procedure BeforeExport; virtual;
procedure BeginExport(AIndex: Integer); virtual;
procedure SaveFieldDefs(ADefs: TQFieldDefs); virtual; abstract;
function WriteRecord(ARec: TQRecord): Boolean; virtual; abstract; // 写出数据
procedure EndExport(AIndex: Integer); virtual;
procedure AfterExport; virtual;
// 导入接口
procedure BeforeImport; virtual;
procedure BeginImport(AIndex: Integer); virtual;
procedure LoadFieldDefs(AFieldDefs: TQFieldDefs); virtual; abstract;
function ReadRecord(ARec: TQRecord): Boolean; virtual; abstract; // 导入数据内容
procedure EndImport(AIndex: Integer); virtual;
procedure AfterImport; virtual;
// 进度
procedure DoProgress(AStep: TQConvertStep; AProgress, ATotal: Integer);
procedure RemoveChild(AIndex: Integer);
function GetActiveRecCount: Integer; virtual;
procedure SetFStreamProcessors(const Value: TQStreamProcessors);
property ActiveDataSet: Integer read FActiveDataSet write FActiveDataSet;
property DataSetCount: Integer read FDataSetCount write FDataSetCount;
property StartOffset: Int64 read FStartOffset;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
/// <summary>
procedure LoadFromStream(ADataSet: TQDataSet; AStream: TStream); overload;
procedure LoadFromFile(ADataSet: TQDataSet; AFileName: QStringW); overload;
procedure LoadFromConverter(AConverter: TQConverter;
ASourceStream, ATargetStream: TStream); overload;
procedure LoadFromConverter(AConverter: TQConverter;
ASourceFile, ATargetFile: QStringW); overload;
procedure LoadFromConverter(AConverter: TQConverterClass;
ASourceStream, ATargetStream: TStream); overload;
procedure LoadFromConverter(AConverter: TQConverterClass;
ASourceFile, ATargetFile: QStringW); overload;
procedure SaveToStream(ADataSet: TQDataSet; AStream: TStream); overload;
procedure SaveToFile(ADataSet: TQDataSet; AFileName: QStringW); overload;
procedure SaveToConverter(AConverter: TQConverter;
ASourceStream, ATargetStream: TStream); overload;
procedure SaveToConverter(AConverter: TQConverter;
ASourceFile, ATargetFile: QStringW); overload;
procedure SaveToConverter(AConverter: TQConverterClass;
ASourceStream, ATargetStream: TStream); overload;
procedure SaveToConverter(AConverter: TQConverterClass;
ASourceFile, ATargetFile: QStringW); overload;
property ActiveRecCount: Integer read GetActiveRecCount;
published
property ExportRanges: TQExportRanges read FExportRanges
write FExportRanges; // 导出范围选择
property OnProgress: TQDataConveterProgress read FOnProgress
write FOnProgress;
property DataSet: TQDataSet read FDataSet write SetDataSet;
property StreamProcessors: TQStreamProcessors read FStreamProcessors
write SetFStreamProcessors;
end;
{ 复制数据来源类型,可取以下值之一:
<table>
取值 备注
-------------- -------------
dcmUnknown 未知来源
dcmView 当前用户查看到的数据
dcmCurrents 当前显示的原始数据
dcmOrigins 更改之前的原始数据
dcmInserted 新插入的数据
dcmDeleted 已删除但未提交的数据
dcmModified 修改过的数据
dcmChanged 所有变更的数据
dcmSorted 排序后的数据
dcmFiltered 按表达式过滤后的数据
dcmMetaOnly 仅复制表结构,不复制数据
</table> }
TQDataCopySource = (dcmUnknown, dcmView, dcmCurrents, dcmOrigins, dcmInserted,
dcmDeleted, dcmModified, dcmChanged, dcmSorted, dcmFiltered, dcmMetaOnly);
/// <summary> 数据集打开方法,内部使用</summary>
/// <list>
/// <item><term>dsomByCreate</term><description>通过CreateDataSet创建内存数据集</description></item>
/// <item><term>dsomByProvider</term><description>通过脚本从TQProvider打开</description></item>
/// <item><term>dsomByConverter</term><description>从转换器加载</description></item>
/// <item><term>dsomByClone</term><description>从源克隆得到</description></item>
/// <item><term>dsomByCopy</term><description>从源复制得到</description></item>
/// </list>
TQDataSetOpenMethod = (dsomByCreate, dsomByProvider, dsomByConverter,
dsomByClone, dsomByCopy);
/// <summary>数据集对象允许的编辑操作</summary>
/// <list>
/// <item><term>deaInsert</term><description>插入操作</description></item>
/// <item><term>deaEdit</term><description>编辑操作</description></item>
/// <item><term>deaDelete</term><description>删除操作</description></item>
/// </list>
TQDataSetEditAction = (deaInsert, deaEdit, deaDelete);
TQDataSetEditActions = set of TQDataSetEditAction;
/// <summary>
/// <list>
/// <item><term>dmmAppend</term><description>追加到已有的结果集后面</description></item>
/// <item><term>dmmReplace</term><description>替换已有的结果集</description></item>
/// <item><term>dmmMerge</term><description>融合,重复的记录会被忽略</description></item>
/// </list>
TQDataMergeMethod = (dmmAppend, dmmReplace, dmmMerge);
/// <summary>记录变更通知类型,用于克隆的数据集之间相互通知变更信息</summary>
TQRecordChangeNotify = (rcnDeleted, rcnInserted, rcnModified);
TQBlobStream = class(TStream)
protected
FMode: TBlobStreamMode; // 读写模式
FField: TBlobField; // 关联字段
FData: TQValue; // 数据内容
FOriginValue: PQValue; // 原始的字段值
function GetSize: Int64; override;
procedure SetSize(NewSize: Longint); overload; override;
public
constructor Create(AField: TBlobField; AMode: TBlobStreamMode); overload;
destructor Destroy; override;
function Read(var Buffer; Count: Longint): Longint; overload; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
procedure Truncate;
end;
TQCustomSortEvent = procedure(ADataSet: TQDataSet;
ARecord1, ARecord2: TQRecord; var AResult: Integer) of object;
TQRecordCompareProc = function(AExp: PQSortExp; ARec1, ARec2: TQRecord)
: Integer of object;
// 记录哈希的结果
TQRecordHash = record
HashCode: Cardinal; // 普通哈希值,如果一致时,再计算并比较MD5的哈希值
MD5: TQMD5Digest; // MD5哈希值,默认不计算,只有HashCode一致时才会进一步计算
Rec: TQRecord; // 原始记录指针
FlatValues: TBytes; // 原始值平面化后的值
MD5Hashed: Boolean; // 是否已经哈希过MD5
end;
PQRecordHash = ^TQRecordHash;
TQDiffCache = record
HashTable: TQHashTable;
Fields: TQFieldDefArray;
end;
TQMasterDataLink = class(TMasterDataLink)
protected
procedure ActiveChanged; override;
procedure RecordChanged(Field: TField); override;
end;
TQHashDupFoundEvent = procedure(ATable: TQHashTable; AHash: PQRecordHash;
AParam: Pointer) of object;
{$IF RTLVersion>=23}
[ComponentPlatformsAttribute(pidWin32 or pidWin64{$IF RTLVersion>=24} or
pidOSX32{$IFEND}{$IF RTLVersion>=25} or pidiOSSimulator or
pidiOSDevice{$IFEND}{$IF RTLVersion>=26} or
pidAndroid{$IFEND}{$IF RTLVersion>=29} or pidiOSDevice32 or
pidiOSDevice64{$IFEND})]
{$IFEND}
TQDataSet = class(TDataSet, IQRecords)
private
procedure SetMasterFields(const Value: QStringW);
procedure SetMasterSource(const Value: TDataSource);
function GetMasterSource: TDataSource;
protected
FProvider: TQProvider; // 数据提供者
FConverter: TQConverter; // 数据转换器
FHandle: THandle; // 从提供者获取数据的句柄,当内存表使用时,始终为空
FChecks: TQLocalChecks; // 本地约束检查
// 记录列表
FOriginRecords: TQRecords; // 原始记录列表
FLoadedRecordCount: Integer;