@@ -60,9 +60,102 @@ func compileTimeHash[T](original: static[T]): CachedHash[T] =
60
60
type Statement* = object
61
61
raw*: ptr RawStatement
62
62
63
+ type
64
+ AuthorizerResult* {.pure, size: sizeof(cint ).} = enum
65
+ ok = 0,
66
+ deny = 1,
67
+ ignore = 2
68
+ AuthorizerActionCode* {.pure, size: sizeof(cint ).} = enum
69
+ # action code # arg3 arg4
70
+ copy = 0, # No longer used
71
+ create_index = 1, # Index Name Table Name
72
+ create_table = 2, # Table Name NULL
73
+ create_temp_index = 3, # Index Name Table Name
74
+ create_temp_table = 4, # Table Name NULL
75
+ create_temp_trigger = 5, # Trigger Name Table Name
76
+ create_temp_view = 6, # View Name NULL
77
+ create_trigger = 7, # Trigger Name Table Name
78
+ create_view = 8, # View Name NULL
79
+ delete = 9, # Table Name NULL
80
+ drop_index = 10, # Index Name Table Name
81
+ drop_table = 11, # Table Name NULL
82
+ drop_temp_index = 12, # Index Name Table Name
83
+ drop_temp_table = 13, # Table Name NULL
84
+ drop_temp_trigger = 14, # Trigger Name Table Name
85
+ drop_temp_view = 15, # View Name NULL
86
+ drop_trigger = 16, # Trigger Name Table Name
87
+ drop_view = 17, # View Name NULL
88
+ insert = 18, # Table Name NULL
89
+ pragma = 19, # Pragma Name 1st arg or NULL
90
+ read = 20, # Table Name Column Name
91
+ select = 21, # NULL NULL
92
+ transaction = 22, # Operation NULL
93
+ update = 23, # Table Name Column Name
94
+ attach = 24, # Filename NULL
95
+ detach = 25, # Database Name NULL
96
+ alter_table = 26, # Database Name Table Name
97
+ reindex = 27, # Index Name NULL
98
+ analyze = 28, # Table Name NULL
99
+ create_vtable = 29, # Table Name Module Name
100
+ drop_vtable = 30, # Table Name Module Name
101
+ function = 31, # NULL Function Name
102
+ savepoint = 32, # Operation Savepoint Name
103
+ recursive = 33, # NULL NULL
104
+ AuthorizerRequest* = ref object
105
+ case action_code*: AuthorizerActionCode
106
+ of create_index, create_temp_index, drop_index, drop_temp_index:
107
+ index_name*: string
108
+ index_table_name*: string
109
+ of create_table, create_temp_table, delete, drop_table, drop_temp_table, insert, analyze:
110
+ table_name*: string
111
+ of create_temp_trigger, create_trigger, drop_temp_trigger, drop_trigger:
112
+ trigger_name*: string
113
+ trigger_table_name*: string
114
+ of create_temp_view, create_view, drop_temp_view, drop_view:
115
+ view_name*: string
116
+ of pragma:
117
+ pragma_name*: string
118
+ pragma_arg*: Option[string ]
119
+ of read, update:
120
+ target_table_name*: string
121
+ column_name*: string
122
+ of select, recursive, copy:
123
+ discard
124
+ of transaction:
125
+ transaction_operation*: string
126
+ of attach:
127
+ filename*: string
128
+ of detach:
129
+ database_name*: string
130
+ of alter_table:
131
+ alter_database_name*: string
132
+ alter_table_name*: string
133
+ of reindex:
134
+ reindex_index_name*: string
135
+ of create_vtable, drop_vtable:
136
+ vtable_name*: string
137
+ module_name*: string
138
+ of function:
139
+ # no arg3
140
+ function_name*: string
141
+ of savepoint:
142
+ savepoint_operation*: string
143
+ savepoint_name*: string
144
+ SqliteRawAuthorizer* = proc(
145
+ userdata: pointer ,
146
+ action_code: AuthorizerActionCode,
147
+ arg3, arg4, arg5, arg6: cstring ): AuthorizerResult {.cdecl.}
148
+ RawAuthorizer* = proc(
149
+ action_code: AuthorizerActionCode,
150
+ arg3, arg4, arg5, arg6: Option[string ]): AuthorizerResult
151
+ Authorizer* = proc(request: AuthorizerRequest): AuthorizerResult
152
+ WrapAuthorizer = object
153
+ authorizer: RawAuthorizer
154
+
63
155
type Database* = object
64
156
raw*: ptr RawDatabase
65
157
stmtcache: Table[CachedHash[string ], ref Statement]
158
+ authorizer: ref WrapAuthorizer
66
159
67
160
type ResultCode* {.pure.} = enum
68
161
sr_ok = 0,
@@ -374,6 +467,7 @@ proc sqlite3_prepare_v3*(db: ptr RawDatabase, sql: cstring, nbyte: int, flags: P
374
467
proc sqlite3_finalize*(st: ptr RawStatement): ResultCode {.sqlite3linkage.}
375
468
proc sqlite3_reset*(st: ptr RawStatement): ResultCode {.sqlite3linkage.}
376
469
proc sqlite3_step*(st: ptr RawStatement): ResultCode {.sqlite3linkage.}
470
+ proc sqlite3_set_authorizer*(db: ptr RawDatabase, auth: SqliteRawAuthorizer, userdata: pointer ): ResultCode {.sqlite3linkage.}
377
471
proc sqlite3_bind_parameter_index*(st: ptr RawStatement, name: cstring ): int {.sqlite3linkage.}
378
472
proc sqlite3_bind_blob64*(st: ptr RawStatement, idx: int , buffer: pointer , len: int , free: SqliteDestroctor): ResultCode {.sqlite3linkage.}
379
473
proc sqlite3_bind_double*(st: ptr RawStatement, idx: int , value: float64 ): ResultCode {.sqlite3linkage.}
@@ -444,6 +538,107 @@ proc initDatabase*(
444
538
sqliteCheck sqlite3_open_v2(filename, addr result .raw, flags, vfs)
445
539
result .stmtcache = initTable[CachedHash[string ], ref Statement]()
446
540
541
+ proc toS(s: cstring ): Option[string ] =
542
+ if s == nil:
543
+ result = none(string )
544
+ else:
545
+ result = some($s)
546
+
547
+ proc setAuthorizer*(db: var Database, callback: RawAuthorizer = nil) =
548
+ let userdata: ref WrapAuthorizer = new(WrapAuthorizer)
549
+ userdata.authorizer = callback
550
+
551
+ proc raw_callback(
552
+ userdata: pointer ,
553
+ action_code: AuthorizerActionCode,
554
+ arg3, arg4, arg5, arg6: cstring ): AuthorizerResult {.cdecl.} =
555
+ let callback = cast[ref WrapAuthorizer](userdata).authorizer
556
+ callback(action_code, arg3.toS(), arg4.toS(), arg5.toS(), arg6.toS())
557
+
558
+ var res: ResultCode
559
+ if callback == nil:
560
+ res = db.raw.sqlite3_set_authorizer(nil, nil)
561
+ else:
562
+ res = db.raw.sqlite3_set_authorizer(raw_callback, cast[pointer ](userdata))
563
+ db.authorizer = userdata
564
+ if res != ResultCode.sr_ok:
565
+ raise newSQLiteError res
566
+
567
+ proc setAuthorizer*(db: var Database, callback: Authorizer = nil) =
568
+ var raw_callback: RawAuthorizer = nil
569
+ if callback != nil:
570
+ raw_callback = proc(code: AuthorizerActionCode, arg3, arg4, arg5, arg6: Option[string ]): AuthorizerResult =
571
+ var req: AuthorizerRequest
572
+ case code
573
+ of create_index, create_temp_index, drop_index, drop_temp_index:
574
+ req = AuthorizerRequest(
575
+ action_code: code,
576
+ index_name: arg3.get,
577
+ index_table_name: arg4.get)
578
+ of create_table, create_temp_table, delete, drop_table, drop_temp_table, insert, analyze:
579
+ req = AuthorizerRequest(
580
+ action_code: code,
581
+ table_name: arg3.get)
582
+ of create_temp_trigger, create_trigger, drop_temp_trigger, drop_trigger:
583
+ req = AuthorizerRequest(
584
+ action_code: code,
585
+ trigger_name: arg3.get,
586
+ trigger_table_name: arg4.get)
587
+ of create_temp_view, create_view, drop_temp_view, drop_view:
588
+ req = AuthorizerRequest(
589
+ action_code: code,
590
+ view_name: arg3.get)
591
+ of pragma:
592
+ req = AuthorizerRequest(
593
+ action_code: code,
594
+ pragma_name: arg3.get,
595
+ pragma_arg: arg4)
596
+ of read, update:
597
+ req = AuthorizerRequest(
598
+ action_code: code,
599
+ target_table_name: arg3.get,
600
+ column_name: arg4.get)
601
+ of select, recursive, copy:
602
+ req = AuthorizerRequest(action_code: code)
603
+ of transaction:
604
+ req = AuthorizerRequest(
605
+ action_code: code,
606
+ transaction_operation: arg3.get)
607
+ of attach:
608
+ req = AuthorizerRequest(
609
+ action_code: code,
610
+ filename: arg3.get)
611
+ of detach:
612
+ req = AuthorizerRequest(
613
+ action_code: code,
614
+ database_name: arg3.get)
615
+ of alter_table:
616
+ req = AuthorizerRequest(
617
+ action_code: code,
618
+ alter_database_name: arg3.get,
619
+ alter_table_name: arg4.get)
620
+ of reindex:
621
+ req = AuthorizerRequest(
622
+ action_code: code,
623
+ reindex_index_name: arg3.get)
624
+ of create_vtable, drop_vtable:
625
+ req = AuthorizerRequest(
626
+ action_code: code,
627
+ vtable_name: arg3.get,
628
+ module_name: arg4.get)
629
+ of function:
630
+ req = AuthorizerRequest(
631
+ action_code: code,
632
+ # no arg3
633
+ function_name: arg4.get)
634
+ of savepoint:
635
+ req = AuthorizerRequest(
636
+ action_code: code,
637
+ savepoint_operation: arg3.get,
638
+ savepoint_name: arg4.get)
639
+ return callback(req)
640
+ db.setAuthorizer(raw_callback)
641
+
447
642
proc changes*(st: var Database): int =
448
643
sqlite3_changes st.raw
449
644
0 commit comments