11import ctypes
2+ from collections .abc import Callable
3+ from ctypes import c_void_p
4+
25import objectbox .c as c
36from objectbox import Store
4- from enum import Enum , auto
7+ from enum import Enum , auto , IntEnum
8+
9+ from objectbox .c import OBX_sync_listener_login
10+
511
612class SyncCredentials :
713
@@ -86,6 +92,15 @@ class SyncLoginEvent:
8692 CREDENTIALS_REJECTED = 'credentials_rejected'
8793 UNKNOWN_ERROR = 'unknown_error'
8894
95+ class SyncCode (IntEnum ):
96+ OK = 20
97+ REQ_REJECTED = 40
98+ CREDENTIALS_REJECTED = 43
99+ UNKNOWN = 50
100+ AUTH_UNREACHABLE = 53
101+ BAD_VERSION = 55
102+ CLIENT_ID_TAKEN = 61
103+ TX_VIOLATED_UNIQUE = 71
89104
90105class SyncChange :
91106 def __init__ (self , entity_id : int , entity : type , puts : list [int ], removals : list [int ]):
@@ -94,11 +109,36 @@ def __init__(self, entity_id: int, entity: type, puts: list[int], removals: list
94109 self .puts = puts
95110 self .removals = removals
96111
112+ class SyncLoginListener :
113+
114+ def on_logged_in (self ):
115+ pass
116+
117+ def on_login_failed (self , sync_login_code : SyncCode ):
118+ pass
119+
120+ class SyncConnectionListener :
121+
122+ def on_connected (self ):
123+ pass
124+
125+ def on_disconnected (self ):
126+ pass
127+
128+ class SyncErrorListener :
129+
130+ def on_error (self , sync_error_code : int ):
131+ pass
97132
98133class SyncClient :
99134
100- def __init__ (self , store : Store , server_urls : list [str ], credentials : list [ SyncCredentials ],
135+ def __init__ (self , store : Store , server_urls : list [str ],
101136 filter_variables : dict [str , str ] | None = None ):
137+ self .__c_login_listener = None
138+ self .__c_login_failure_listener = None
139+ self .__c_connect_listener = None
140+ self .__c_disconnect_listener = None
141+ self .__c_error_listener = None
102142 if not server_urls :
103143 raise ValueError ("Provide at least one server URL" )
104144
@@ -109,14 +149,13 @@ def __init__(self, store: Store, server_urls: list[str], credentials: list[SyncC
109149 # 'Please visit https://objectbox.io/sync/ for options.')
110150
111151 self .__store = store
112- self .__server_urls = server_urls
113- self .__credentials = credentials
152+ self .__server_urls = [url .encode ('utf-8' ) for url in server_urls ]
114153
115- server_urls = [url .encode ('utf-8' ) for url in server_urls ]
116- self .__c_sync_client_ptr = c .obx_sync_urls (store .c_store (), c .c_array_pointer (server_urls , ctypes .c_char_p ),
117- len (server_urls ))
154+ self .__c_sync_client_ptr = c .obx_sync_urls (store .c_store (), c .c_array_pointer (self .__server_urls , ctypes .c_char_p ),
155+ len (self .__server_urls ))
118156
119157 def set_credentials (self , credentials : SyncCredentials ):
158+ self .__credentials = credentials
120159 if isinstance (credentials , SyncCredentialsNone ):
121160 c .obx_sync_credentials (self .__c_sync_client_ptr , credentials .type , None , 0 )
122161 elif isinstance (credentials , SyncCredentialsUserPassword ):
@@ -181,3 +220,42 @@ def close(self):
181220
182221 def is_closed (self ) -> bool :
183222 return self .__c_sync_client_ptr is None
223+
224+ def set_login_listener (self , login_listener : SyncLoginListener ):
225+ self .__c_login_listener = c .OBX_sync_listener_login (lambda arg : login_listener .on_logged_in ())
226+ self .__c_login_failure_listener = c .OBX_sync_listener_login_failure (lambda arg , sync_login_code : login_listener .on_login_failed (sync_login_code ))
227+ c .obx_sync_listener_login (
228+ self .__c_sync_client_ptr ,
229+ self .__c_login_listener ,
230+ None
231+ )
232+ c .obx_sync_listener_login_failure (
233+ self .__c_sync_client_ptr ,
234+ self .__c_login_failure_listener ,
235+ None
236+ )
237+
238+ def set_connection_listener (self , connection_listener : SyncConnectionListener ):
239+ self .__c_connect_listener = c .OBX_sync_listener_connect (lambda arg : connection_listener .on_connected ())
240+ self .__c_disconnect_listener = c .OBX_sync_listener_disconnect (lambda arg : connection_listener .on_disconnected ())
241+ c .obx_sync_listener_connect (
242+ self .__c_sync_client_ptr ,
243+ self .__c_connect_listener ,
244+ None
245+ )
246+ c .obx_sync_listener_disconnect (
247+ self .__c_sync_client_ptr ,
248+ self .__c_disconnect_listener ,
249+ None
250+ )
251+
252+ def set_error_listener (self , error_listener : SyncErrorListener ):
253+ self .__c_error_listener = c .OBX_sync_listener_error (lambda arg , sync_error_code : error_listener .on_error (sync_error_code ))
254+ c .obx_sync_listener_error (
255+ self .__c_sync_client_ptr ,
256+ self .__c_error_listener ,
257+ None
258+ )
259+
260+ def wait_for_logged_in_state (self , timeout_millis : int ):
261+ c .obx_sync_wait_for_logged_in_state (self .__c_sync_client_ptr , timeout_millis )
0 commit comments