@@ -60,9 +60,102 @@ func compileTimeHash[T](original: static[T]): CachedHash[T] =
6060type Statement * = object
6161 raw* : ptr RawStatement
6262
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+
63155type Database * = object
64156 raw* : ptr RawDatabase
65157 stmtcache: Table [CachedHash [string ], ref Statement ]
158+ authorizer: ref WrapAuthorizer
66159
67160type ResultCode * {.pure .} = enum
68161 sr_ok = 0 ,
@@ -374,6 +467,7 @@ proc sqlite3_prepare_v3*(db: ptr RawDatabase, sql: cstring, nbyte: int, flags: P
374467proc sqlite3_finalize * (st: ptr RawStatement ): ResultCode {.sqlite3linkage .}
375468proc sqlite3_reset * (st: ptr RawStatement ): ResultCode {.sqlite3linkage .}
376469proc sqlite3_step * (st: ptr RawStatement ): ResultCode {.sqlite3linkage .}
470+ proc sqlite3_set_authorizer * (db: ptr RawDatabase , auth: SqliteRawAuthorizer , userdata: pointer ): ResultCode {.sqlite3linkage .}
377471proc sqlite3_bind_parameter_index * (st: ptr RawStatement , name: cstring ): int {.sqlite3linkage .}
378472proc sqlite3_bind_blob64 * (st: ptr RawStatement , idx: int , buffer: pointer , len: int , free: SqliteDestroctor ): ResultCode {.sqlite3linkage .}
379473proc sqlite3_bind_double * (st: ptr RawStatement , idx: int , value: float64 ): ResultCode {.sqlite3linkage .}
@@ -444,6 +538,107 @@ proc initDatabase*(
444538 sqliteCheck sqlite3_open_v2 (filename, addr result .raw, flags, vfs)
445539 result .stmtcache = initTable [CachedHash [string ], ref Statement ]()
446540
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+
447642proc changes * (st: var Database ): int =
448643 sqlite3_changes st.raw
449644
0 commit comments