1 using System;
2 using System.Text;
3 using System.Runtime.InteropServices;
4 
5 namespace GigaBaseNet
6 {
7   /// <summary>
8   /// Exception thrown by Gigabase CLI implementation.
9   /// </summary>
10   public class CliError : Exception {
11     public int ErrorCode;
12 
13     ///<summary>
14     /// Constructor of the exception object.
15     /// </summary>
16     /// <param name="Msg">message describing the reason of the fault</param>
CliError(string Msg)17     public CliError(string Msg) : this((int)CLI.ErrorCode.cli_unknown_error, Msg) {}
18     ///<summary>
19     /// Constructor of the exception object.
20     /// </summary>
21     /// <param name="Code">Error code describing the reason of the fault</param>
CliError(int Code)22     public CliError(int Code)   : this(Code, "") {}
23     ///<summary>
24     /// Constructor of the exception object.
25     /// </summary>
26     /// <param name="Code">Error code describing the reason of the fault</param>
27     /// <param name="Msg">Message describing the reason of the fault</param>
CliError(int Code, string Msg)28     public CliError(int Code, string Msg): base(FormatMessage(Code, Msg)) {
29       ErrorCode = Code;
30     }
FormatMessage(int Code, string Msg)31     private static string FormatMessage(int Code, string Msg) {
32       if (Msg != "")
33         Msg += ". " + CLI.CliErrorToStr(Code);
34       else
35         Msg = CLI.CliErrorToStr(Code);
36       return Msg;
37     }
38   }
39 
40 
41   /// <summary>
42   /// GigaBASE CLI interface.
43   /// </summary>
44   public class CLI {
45 
46 #if FASTDB
47 #if LINUX
48     public const string libname = "libfastdb_r.so";
49 #else
50     public const string libname = "FastDB.dll";
51 #endif
52 #else
53 #if LINUX
54     public const string libname = "libgigabase_r.so";
55 #else
56     public const string libname = "GigaBase.dll";
57 #endif
58 #endif
59 
60     //-----------------------------------------
61     // cli_result_code
62     //-----------------------------------------
63     public enum ErrorCode : int {
64       cli_ok                         =  0,
65       cli_bad_address                = -1,
66       cli_connection_refused         = -2,
67       cli_database_not_found         = -3,
68       cli_bad_statement              = -4,
69       cli_parameter_not_found        = -5,
70       cli_unbound_parameter          = -6,
71       cli_column_not_found           = -7,
72       cli_incompatible_type          = -8,
73       cli_network_error              = -9,
74       cli_runtime_error              = -10,
75       cli_bad_descriptor             = -11,
76       cli_unsupported_type           = -12,
77       cli_not_found                  = -13,
78       cli_not_update_mode            = -14,
79       cli_table_not_found            = -15,
80       cli_not_all_columns_specified  = -16,
81       cli_not_fetched                = -17,
82       cli_already_updated            = -18,
83       cli_table_already_exists       = -19,
84       cli_not_implemented            = -20,
85 #if !FASTDB
86       cli_login_failed               = -21,
87       cli_empty_parameter            = -22,
88       cli_closed_connection          = -23,
89 #endif
90 
91       //-----------------------------------------
92       // cli_error_class
93       // Note: When calling CliErrorToStr in TCliErrorHandler subtract 100 from the
94       //       code passed as ErrorClassCode in order to get correct description
95       //-----------------------------------------
96       cli_query_error                = 1  -100,
97       cli_arithmetic_error           = 2  -100,
98       cli_index_out_of_range_error   = 3  -100,
99       cli_database_open_error        = 4  -100,
100       cli_file_error                 = 5  -100,
101       cli_out_of_memory_error        = 6  -100,
102       cli_deadlock                   = 7  -100,
103       cli_null_reference_error       = 8  -100,
104       cli_lock_revoked               = 9  -100,
105       cli_file_limit_exeeded         = 10 -100,
106 
107       //-----------------------------------------
108       // Extended Error Codes
109       //-----------------------------------------
110       cli_error_loading_library      = -200,
111       cli_session_not_assigned       = -201,
112       cli_database_already_open      = -202,
113       cli_invalid_field_size         = -203,
114       cli_empty_query                = -204,
115       cli_item_already_defined       = -205,
116       cli_wrong_inverse_reference    = -206,
117       cli_no_fields_defined          = -207,
118       cli_access_violation           = -208,
119       cli_unknown_error              = -999
120     }
121 
122     //-----------------------------------------
123     // Field Types
124     //-----------------------------------------
125     public enum FieldType : int {
126       cli_oid                        = 0,
127       cli_bool                       = 1,
128       cli_int1                       = 2,
129       cli_int2                       = 3,
130       cli_int4                       = 4,
131       cli_int8                       = 5,
132       cli_real4                      = 6,
133       cli_real8                      = 7,
134       cli_decimal                    = 8,  //{ not supported in FastDB }
135       cli_asciiz                     = 9,  //{ zero terminated string (Get/Set function can be used) }
136       cli_pasciiz                    = 10, //{ pointer to zero terminated string }
137       cli_cstring                    = 11, //{ not supported in FastDB }
138       cli_array_of_oid               = 12,
139       cli_array_of_bool              = 13,
140       cli_array_of_int1              = 14,
141       cli_array_of_int2              = 15,
142       cli_array_of_int4              = 16,
143       cli_array_of_int8              = 17,
144       cli_array_of_real4             = 18,
145       cli_array_of_real8             = 19,
146       cli_array_of_decimal           = 20, //{ not supported in FastDB }
147       cli_array_of_string            = 21,
148       cli_any                        = 22, //{ not supported in FastDB }
149       cli_datetime                   = 23, //{ not supported in FastDB }
150       cli_autoincrement              = 24,
151       cli_rectangle                  = 25, //{ not supported in FastDB }
152       cli_unknown                    = 26,
153       //--- Custom types not supported by the database directly -----
154       cli_subst                            // Reserved for substitution variables
155     };
156 
157     internal static int[] SizeOfCliType =
158       new int[] {
159                   Marshal.SizeOf(typeof(int)),          // cli_oid
160                   Marshal.SizeOf(typeof(bool)),					// cli_bool
161                   Marshal.SizeOf(typeof(sbyte)),				// cli_int1
162                   Marshal.SizeOf(typeof(short)),				// cli_int2
163                   Marshal.SizeOf(typeof(int)),	        // cli_int4
164                   Marshal.SizeOf(typeof(long)),					// cli_int8_t
165                   Marshal.SizeOf(typeof(float)),  			// cli_real4_t
166                   Marshal.SizeOf(typeof(double)),				// cli_real8_t
167                   0, // cli_decimal
168                   0, // cli_asciiz,
169                   0, // cli_pasciiz,
170                   0, // cli_cstring,
171                   0, // cli_array_of_oid,
172                   0, // cli_array_of_bool,
173                   0, // cli_array_of_int1,
174                   0, // cli_array_of_int2,
175                   0, // cli_array_of_int4,
176                   0, // cli_array_of_int8,
177                   0, // cli_array_of_real4,
178                   0, // cli_array_of_real8,
179                   0, // cli_array_of_decimal,
180                   0, // cli_array_of_string,
181                   0, // cli_any,
182                   Marshal.SizeOf(typeof(double)),         // cli_datetime,
183                   Marshal.SizeOf(typeof(int)),          // cli_autoincrement,
184                   0, // cli_rectangle,
185                   0, // cli_unknown
186                   0  // ctSubst
187                 };
188 
CliTypeToStr(FieldType type, bool ExtendedSyntax)189     public static string CliTypeToStr(FieldType type, bool ExtendedSyntax) {
190       StringBuilder s = new StringBuilder("");
191       FieldType ft = type;
192       if (ExtendedSyntax && type >= CLI.FieldType.cli_array_of_oid && type <= CLI.FieldType.cli_array_of_string) {
193         s.Append("array of ");
194         ft = (CLI.FieldType)((int)type - (int)CLI.FieldType.cli_array_of_oid);
195       }
196 
197       switch(ft) {
198         case CLI.FieldType.cli_oid:
199           s.Append((ExtendedSyntax)? "reference" : "(oid)"); break;
200         case CLI.FieldType.cli_bool:
201           s.Append((ExtendedSyntax)? "bool" : "Boolean"); break;
202         case CLI.FieldType.cli_int1:
203           s.Append((ExtendedSyntax)? "int1" : "Byte"); break;
204         case CLI.FieldType.cli_int2:
205           s.Append((ExtendedSyntax)? "int2" : "SmallInt"); break;
206         case CLI.FieldType.cli_autoincrement:
207         case CLI.FieldType.cli_int4:
208           s.Append((ExtendedSyntax)? "int4" : "Integer"); break;
209         case CLI.FieldType.cli_int8:
210           s.Append((ExtendedSyntax)? "int8" : "Int64"); break;
211         case CLI.FieldType.cli_real4:
212           s.Append((ExtendedSyntax)? "real4" : "Single"); break;
213         case CLI.FieldType.cli_datetime:
214           s.Append((ExtendedSyntax)? "real8" : "DateTime"); break;
215         case CLI.FieldType.cli_real8:
216           s.Append((ExtendedSyntax)? "real8" : "Double"); break;
217         case CLI.FieldType.cli_asciiz:
218         case CLI.FieldType.cli_pasciiz:
219           s.Append((ExtendedSyntax)? "string" : "String"); break;
220         default:
221           if (!ExtendedSyntax)
222             s.Append(Enum.GetName(typeof(CLI.FieldType), ft).Substring(4)); break;
223       }
224       return s.ToString();
225     }
226 
IsArrayType(FieldType tp)227     public static bool IsArrayType(FieldType tp) {
228       return tp >= FieldType.cli_array_of_oid && tp <= FieldType.cli_array_of_real8;
229     }
230 
CliCheck(int code, string Msg)231     public static int CliCheck(int code, string Msg) {
232       if (code < 0)
233         throw new CliError(code, Msg);
234       else
235         return code;
236     }
237 
CliCheck(int code)238     public static int CliCheck(int code) {
239       return CliCheck(code, "");
240     }
241 
242     // translate error code to string
CliErrorToStr(int Code)243     public static string CliErrorToStr(int Code) {
244       if (Code >= 0)
245         return null;
246       else
247         switch (Code) {
248           case (int)ErrorCode.cli_bad_address                : return "Invalid format of server URL";
249           case (int)ErrorCode.cli_connection_refused         : return "Connection with server could not be established";
250           case (int)ErrorCode.cli_database_not_found         : return "Database cannot be found";
251           case (int)ErrorCode.cli_bad_statement              : return "Text of SQL statement is not correct";
252           case (int)ErrorCode.cli_parameter_not_found        : return "Parameter was not found in statement";
253           case (int)ErrorCode.cli_unbound_parameter          : return "Parameter was not specified";
254           case (int)ErrorCode.cli_column_not_found           : return "No such colunm in the table";
255           case (int)ErrorCode.cli_incompatible_type          : return "Conversion between application and database type is not possible";
256           case (int)ErrorCode.cli_network_error              : return "Connection with server is broken";
257           case (int)ErrorCode.cli_runtime_error              : return "Error during query execution";
258           case (int)ErrorCode.cli_bad_descriptor             : return "Invalid statement/session description";
259           case (int)ErrorCode.cli_unsupported_type           : return "Unsupported type for parameter or column";
260           case (int)ErrorCode.cli_not_found                  : return "Record was not found";
261           case (int)ErrorCode.cli_not_update_mode            : return "Attempt to update records selected by view only cursor";
262           case (int)ErrorCode.cli_table_not_found            : return "There is no table with specified name in the database";
263           case (int)ErrorCode.cli_not_all_columns_specified  : return "Insert statement doesn''t specify values for all table columns";
264           case (int)ErrorCode.cli_not_fetched                : return "cli_fetch method was not called";
265           case (int)ErrorCode.cli_already_updated            : return "cli_update method was invoked more than once for the same record";
266           case (int)ErrorCode.cli_table_already_exists       : return "Attempt to create existing table";
267           case (int)ErrorCode.cli_not_implemented            : return "Function is not implemented";
268             //----- Severe Error Class Codes---------
269           case (int)ErrorCode.cli_query_error                : return "Query error";
270           case (int)ErrorCode.cli_arithmetic_error           : return "Arithmetic error";
271           case (int)ErrorCode.cli_index_out_of_range_error   : return "Index out of range";
272           case (int)ErrorCode.cli_database_open_error        : return "Database open error";
273           case (int)ErrorCode.cli_file_error                 : return "File error";
274           case (int)ErrorCode.cli_out_of_memory_error        : return "Out of memory";
275           case (int)ErrorCode.cli_deadlock                   : return "Deadlock detected";
276           case (int)ErrorCode.cli_null_reference_error       : return "Null reference";
277           case (int)ErrorCode.cli_lock_revoked               : return "Lock revoked";
278           case (int)ErrorCode.cli_file_limit_exeeded         : return "File limit exeeded";
279             //----- Custom Error Codes---------------
280           case (int)ErrorCode.cli_error_loading_library      : return "Error loading library";
281           case (int)ErrorCode.cli_session_not_assigned       : return "Session not assigned or not connected";
282           case (int)ErrorCode.cli_database_already_open      : return "Database already open";
283           case (int)ErrorCode.cli_invalid_field_size         : return "Invalid field size";
284           case (int)ErrorCode.cli_empty_query                : return "Query SQL text is not assigned";
285           case (int)ErrorCode.cli_item_already_defined       : return "Field/Variable is already defined";
286           case (int)ErrorCode.cli_wrong_inverse_reference    : return "Wrong inverse reference";
287           case (int)ErrorCode.cli_no_fields_defined          : return "No fields defined";
288           case (int)ErrorCode.cli_access_violation           : return "Access Violation";
289           default:						                                 return String.Format("({0})", Code);
290         }
291     }
292 
293     [Flags]
294       public enum CliOpenAttribute : int {
295       oaReadWrite      = 0x00, //cli_open_default
296       oaReadOnly			 = 0x01, //cli_open_readonly
297       oaTruncate       = 0x02, //cli_open_truncate
298       oaOpenConcurrent = 0x04  //cli_open_concurrent
299     };
300 
301     /*=====================================================================
302      * cli_open
303      *     Establish connection with the server
304      * Parameters:
305      *     server_url - zero terminated string with server address and port,
306      *                  for example "localhost:5101", "195.239.208.240:6100",...
307      *     max_connect_attempts  - number of attempts to establish connection
308      *     reconnect_timeout_sec - timeput in seconds between connection attempts
309      *  Gigabase users:
310      *  ===============
311      *  user_name - user name for login
312      *  password  - password for login
313      *  pooled_connection - if not 0, then connection will be allocated from the connection pool
314      *
315      * Returns:
316      *     >= 0 - connectiondescriptor to be used in all other cli calls
317      *     <  0 - error code as described in cli_result_code enum
318      */
319     [DllImport(libname,
320        CharSet           = CharSet.Ansi,  // We want ANSI String
321        CallingConvention = CallingConvention.Cdecl)]
cli_open( string ServerURL, int MaxConnectAttempts, int ReconnectTimeoutSec , string UserName , string Password , bool PooledConnection )322     internal static extern int cli_open(
323       string ServerURL,
324       int MaxConnectAttempts,
325       int ReconnectTimeoutSec
326 #if !FASTDB
327         , string UserName
328         , string Password
329         , bool PooledConnection
330 #endif
331       );
332 
333     /*=====================================================================
334      * cli_create
335      *     Create connection to the local database
336      * Parameters:
337      *     databaseName - name of the database
338      *     fileName - path to the database file
339      *     transactionCommitDelay - trasnaction commit delay (specify 0 to disable)
340      *     openAttr - mask of cli_open_attributes
341      *     initDatabaseSize - initial size of the database
342      *     extensionQuantum - database extension quantum
343      *     initIndexSize - initial size of object index
344      *     fileSizeLimit - limit for file size (0 - unlimited)
345      * Returns:
346      *     >= 0 - connection descriptor to be used in all other cli calls
347      *     <  0 - error code as described in cli_result_code enum
348      */
349 
350     [DllImport(libname,
351        CharSet           = CharSet.Ansi,  // We want ANSI String
352        CallingConvention = CallingConvention.Cdecl)]
cli_create( string databasePath, uint TransactionCommitDelay, int openAttr, int PoolSize )353     internal static extern int cli_create(
354 #if !FASTDB
355       string databasePath,
356       uint TransactionCommitDelay,
357       int  openAttr,
358       int  PoolSize
359 #else
360       string databaseName,   //[MarshalAs(UnmanagedType.LPStr)] string databaseName,
361       string filePath,       //[MarshalAs(UnmanagedType.LPStr)] string filePath,
362       uint   transactionCommitDelay,
363       int    openAttr,
364       int    initDatabaseSize,
365       int    extensionQuantum,
366       int    initIndexSize,
367       int    fileSizeLimit
368 #endif
369       );
370 
371     /*=====================================================================
372      * cli_create_replication_node
373      *     Create connection to the local database with support of replication
374      * Parameters:
375      *     nodeId - node identifier: 0 <= nodeId < nServers
376      *     nServers - number of replication nodes (primary + standby)
377      *     nodeNames - array with URLs of the nodes (address:port)
378      *     databaseName - name of the database
379      *     fileName - path to the database file
380      *     transactionCommitDelay - trasnaction commit delay (specify 0 to disable)
381      *     openAttr - mask of cli_open_attributes (to allow concurrent read access to replication node,
382      *                cli_open_concurrent attribute should be set)
383      *     initDatabaseSize - initial size of the database
384      *     extensionQuantum - database extension quantum
385      *     initIndexSize - initial size of object index
386      *     fileSizeLimit - limit for file size (0 - unlimited)
387      * Returns:
388      *     >= 0 - connection descriptor to be used in all other cli calls
389      *     <  0 - error code as described in cli_result_code enum
390      */
391 
392     [DllImport(libname,
393        CharSet           = CharSet.Ansi,  // We want ANSI String
394        CallingConvention = CallingConvention.Cdecl)]
cli_create_replication_node( int nodeId, int nServers, [In, Out] String[] nodeNames, string databaseName, string filePath, int openAttr, int initDatabaseSize, int extensionQuantum, int initIndexSize, int fileSizeLimit)395     internal static extern int cli_create_replication_node(
396       int                nodeId,
397       int                nServers,
398       [In, Out] String[] nodeNames,
399       string             databaseName,
400       string             filePath,
401       int                openAttr,
402       int                initDatabaseSize,
403       int                extensionQuantum,
404       int                initIndexSize,
405       int                fileSizeLimit);
406 
407     /*=====================================================================
408       * cli_close
409       *     Close session
410       * Parameters:
411       *     session - session descriptor returned by cli_open
412       * Returns:
413       *     result code as described in cli_result_code enum
414       */
415     [DllImport(libname,
416        CharSet           = CharSet.Ansi,  // We want ANSI String
417        CallingConvention = CallingConvention.Cdecl)]
cli_close(int session)418     internal static extern int cli_close(int session);
419 
420     /*=====================================================================
421      * cli_statement
422      *     Specify SubSQL statement to be executed at server
423      *     Binding to the parameters and columns can be established
424      * Parameters:
425      *     session - session descriptor returned by cli_open
426      *     stmt    - zero terminated string with SubSQL statement
427      * Returns:
428      *     >= 0 - statement descriptor
429      *     <  0 - error code as described in cli_result_code enum
430      */
431     [DllImport(libname,
432        CharSet           = CharSet.Ansi,  // We want ANSI String
433        CallingConvention = CallingConvention.Cdecl)]
cli_statement(int session, string stmt)434     internal static extern int cli_statement(int session, string stmt);
435 
436     /*=====================================================================
437      * cli_parameter
438      *     Bind parameter to the statement
439      * Parameters:
440      *     statement  - statememt descriptor returned by cli_statement
441      *     param_name - zero terminated string with parameter name
442      *                  Paramter name should start with '%'
443      *     var_type   - type of variable as described in CliVarType enum.
444      *                  Only scalar and zero terminated string types are supported.
445      *     var_ptr    - pointer to the variable
446      * Returns:
447      *     result code as described in cli_result_code enum
448      */
449     [DllImport(libname,
450        CharSet           = CharSet.Ansi,  // We want ANSI String
451        CallingConvention = CallingConvention.Cdecl)]
cli_parameter( int statement, string param_name, int var_type, IntPtr var_ptr)452     internal static extern int cli_parameter(
453       int       statement,
454       string    param_name,
455       int       var_type,
456       IntPtr    var_ptr);
457 
458     /*=====================================================================
459      * cli_column
460      *     Bind extracted column of select or insert statement
461      * Parameters:
462      *     statement   - statememt descriptor returned by cli_statement
463      *     column_name - zero terminated string with column name
464      *     var_type    - type of variable as described in CliVarType enum
465      *     var_len     - pointer to the variable to hold length of array variable.
466      *                   This variable should be assigned the maximal length
467      *                   of the array/string buffer, pointed by var_ptr.
468      *                   After the execution of the statement it is assigned the
469      *                   real length of the fetched array/string. If it is large
470      *                   than length of the buffer, then only part of the array
471      *                   will be placed in the buffer, but var_len still will
472      *                   contain the actual array length.
473      *     var_ptr     - pointer to the variable
474      * Returns:
475      *     result code as described in cli_result_code enum
476      */
477     [DllImport(libname,
478        CharSet           = CharSet.Ansi,  // We want ANSI String
479        CallingConvention = CallingConvention.Cdecl)]
cli_column( int statement, string column_name, int var_type, ref int var_len, IntPtr var_data)480     public static extern int cli_column(
481        int       statement,
482        string    column_name,
483        int       var_type,
484        ref int   var_len,
485        IntPtr var_data);
486 
487     [ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
488     public struct UnmanagedBuffer {
489       public int    type;
490       public int    capacity;
491       public int    size;
492       public bool   fetch_data;
493       public IntPtr data;
494     }
495 
496     /* The C# does not allow you to specify the calling convention of the callback.
497      * It is just one of the C# limitations. IL, managed C++ and the runtime itself
498      * supports the cdecl calling convention for delegates through
499      * modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) on the
500      * internal Invoke method of the delegate. Run ildasm on a small example in
501      * managed C++ if you want to know the exact syntax.
502      */
503 
504      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
CliColumnSetEx( int var_type, IntPtr var_ptr, int len, [MarshalAs(UnmanagedType.LPStr)] string column_name, int statement, IntPtr source_ptr, void* buffer)505     internal unsafe delegate IntPtr CliColumnSetEx(
506       int       var_type,
507       IntPtr    var_ptr,
508       int       len,
509       [MarshalAs(UnmanagedType.LPStr)]
510       string    column_name,
511       int       statement,
512       IntPtr    source_ptr,
513       void* buffer);
514 
515      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
CliColumnGetEx( int var_type, IntPtr var_ptr, ref int len, string column_name, int statement, void* buffer)516     internal unsafe delegate IntPtr CliColumnGetEx(
517       int     var_type,
518       IntPtr  var_ptr,
519       ref int len,
520       string column_name, int statement,
521       void* buffer);
522 
523 
524     /*=====================================================================
525      * cli_array_column
526      *     Specify get/set functions for the array column
527      * Parameters:
528      *     statement   - statememt descriptor returned by cli_statement
529      *     column_name - zero terminated string with column name
530      *     var_type    - type of variable as described in CliVarType enum
531      *     var_ptr     - pointer to the variable
532      *     set         - function which will be called to construct fetched
533      *                   field. It receives pointer to the variable,
534      *                   length of the fetched array and returns pointer to th
535      *                   array's elements
536      *     get         - function which will be called to update the field in the
537      *                   database. Given pointer to the variable, it should return
538      *                   pointer to the array elements and store length of the
539      *                   array to the variable pointer by len parameter
540      * Returns:
541      *     result code as described in cli_result_code enum
542      */
543     [DllImport(libname,
544        CharSet           = CharSet.Ansi,  // We want ANSI String
545        CallingConvention = CallingConvention.Cdecl)]
cli_array_column_ex( int statement, string column_name, int var_type, IntPtr var_ptr, CliColumnSetEx SetCallback, CliColumnGetEx GetCallback, void* user_data)546     internal unsafe static extern int cli_array_column_ex(
547       int            statement,
548       string         column_name,
549       int            var_type,
550       IntPtr         var_ptr,
551       CliColumnSetEx SetCallback,
552       CliColumnGetEx GetCallback,
553       void* user_data);
554 
555     public enum QueryType: int {
556       cli_view_only  = 0,
557       cli_for_update = 1
558     }
559 
560     /*=====================================================================
561      * cli_fetch
562      *     Execute select statement.
563      * Parameters:
564      *     statement    - statememt descriptor returned by cli_statement
565      *     queryType - not zero if fetched rows will be updated
566      * Returns:
567      *     >= 0 - success, for select statements number of fetched rows is returned
568      *     <  0 - error code as described in cli_result_code enum
569      */
570     [DllImport(libname,
571        CharSet           = CharSet.Ansi,  // We want ANSI String
572        CallingConvention = CallingConvention.Cdecl)]
cli_fetch(int statement, QueryType queryType)573     internal static extern int cli_fetch(int statement, QueryType queryType);
574 
575     /*=====================================================================
576      * cli_insert
577      *     Execute insert statement.
578      * Parameters:
579      *     statement  - statememt descriptor returned by cli_statement
580      *     oid        - object identifier of created record.
581      * Returns:
582      *     status code as described in cli_result_code enum
583      */
584     [DllImport(libname,
585        CharSet           = CharSet.Ansi,  // We want ANSI String
586        CallingConvention = CallingConvention.Cdecl)]
cli_insert(int statement, ref uint oid)587     internal static extern int cli_insert(int statement, ref uint oid);
588 
589     /*=====================================================================
590      * cli_get_first
591      *     Get first row of the selection.
592      * Parameters:
593      *     statement  - statememt descriptor returned by cli_statement
594      * Returns:
595      *     result code as described in cli_result_code enum
596      */
597     [DllImport(libname,
598        CharSet           = CharSet.Ansi,  // We want ANSI String
599        CallingConvention = CallingConvention.Cdecl)]
cli_get_first(int statement)600     internal static extern int cli_get_first(int statement);
601 
602     /*=====================================================================
603      * cli_get_last
604      *     Get last row of the selection.
605      * Parameters:
606      *     statement  - statememt descriptor returned by cli_statement
607      * Returns:
608      *     result code as described in cli_result_code enum
609      */
610     [DllImport(libname,
611        CharSet           = CharSet.Ansi,  // We want ANSI String
612        CallingConvention = CallingConvention.Cdecl)]
cli_get_last(int statement)613     internal static extern int cli_get_last(int statement);
614 
615     /*=====================================================================
616      * cli_get_next
617      *     Get next row of the selection. If get_next records is called
618      *     exactly after cli_fetch function call, is will fetch the first record
619      *     in selection.
620      * Parameters:
621      *     statement  - statememt descriptor returned by cli_statement
622      * Returns:
623      *     result code as described in cli_result_code enum
624      */
625     [DllImport(libname,
626        CharSet           = CharSet.Ansi,  // We want ANSI String
627        CallingConvention = CallingConvention.Cdecl)]
cli_get_next(int statement)628     internal static extern int cli_get_next(int statement);
629 
630     /*=====================================================================
631      * cli_get_prev
632      *     Get previous row of the selection. If get_next records is called
633      *     exactly after cli_fetch function call, is will fetch the last record
634      *     in selection.
635      * Parameters:
636      *     statement  - statememt descriptor returned by cli_statement
637      * Returns:
638      *     result code as described in cli_result_code enum
639      */
640     [DllImport(libname,
641        CharSet           = CharSet.Ansi,  // We want ANSI String
642        CallingConvention = CallingConvention.Cdecl)]
cli_get_prev(int statement)643     internal static extern int cli_get_prev(int statement);
644 
645     /*=====================================================================
646      * cli_skip
647      *     Skip specified number of rows.
648      * Parameters:
649      *     statement  - statememt descriptor returned by cli_statement
650      *     n          - number of objects to be skipped
651      *                - if "n" is positive, then this function has the same effect as
652      *                     executing cli_get_next() function "n" times.
653      *                - if "n" is negative, then this function has the same effect as
654      *                     executing cli_get_prev() function "-n" times.
655      *                - if "n"  is zero, this method just reloads current record
656      * Returns:
657      *     result code as described in cli_result_code enum
658      */
659     [DllImport(libname,
660        CharSet           = CharSet.Ansi,  // We want ANSI String
661        CallingConvention = CallingConvention.Cdecl)]
cli_skip(int statement, int n)662     internal static extern int cli_skip(int statement, int n);
663 
664     /*=====================================================================
665      * cli_seek
666      *    Position cursor to the record with specified OID
667      * Parameters:
668      *     statement   - statememt descriptor returned by cli_statement
669      *     oid         - object identifier of the record to which cursor should be positioned
670      * Returns:
671      *     >= 0 - success, position of the record in the selection
672      *     <  0 - error code as described in cli_result_code enum
673      */
674     [DllImport(libname,
675        CharSet           = CharSet.Ansi,  // We want ANSI String
676        CallingConvention = CallingConvention.Cdecl)]
cli_seek(int statement, uint oid)677     internal static extern int cli_seek(int statement, uint oid);
678 
679 
680     /*=====================================================================
681      * cli_get_oid
682      *     Get object identifier of the current record
683      * Parameters:
684      *     statement  - statememt descriptor returned by cli_statement
685      * Returns:
686      *     object identifier or 0 if no object is seleected
687      */
688     [DllImport(libname,
689        CharSet           = CharSet.Ansi,  // We want ANSI String
690        CallingConvention = CallingConvention.Cdecl)]
cli_get_oid(int statement)691     internal static extern uint cli_get_oid(int statement);
692 
693     /*=====================================================================
694      * cli_update
695      *     Update the current row in the selection. You have to set
696      *     for_update parameter of cli_fetch to 1 in order to be able
697      *     to perform updates. Updated value of row fields will be taken
698      *     from bound column variables.
699      * Parameters:
700      *     statement   - statememt descriptor returned by cli_statement
701      * Returns:
702      *     result code as described in cli_result_code enum
703      */
704     [DllImport(libname,
705        CharSet           = CharSet.Ansi,  // We want ANSI String
706        CallingConvention = CallingConvention.Cdecl)]
cli_update(int statement)707     internal static extern int cli_update(int statement);
708 
709     /*=====================================================================
710      * cli_remove
711      *     Remove all selected records. You have to set
712      *     for_update parameter of cli_fetch to 1 in order to be able
713      *     to remove records.
714      * Parameters:
715      *     statement   - statememt descriptor returned by cli_statement
716      * Returns:
717      *     result code as described in cli_result_code enum
718      */
719     [DllImport(libname,
720        CharSet           = CharSet.Ansi,  // We want ANSI String
721        CallingConvention = CallingConvention.Cdecl)]
cli_remove(int statement)722     internal static extern int cli_remove(int statement);
723 
724     /*=====================================================================
725      * cli_free
726      *     Deallocate statement and all associated data
727      * Parameters:
728      *     statement   - statememt descriptor returned by cli_statement
729      * Returns:
730      *     result code as described in cli_result_code enum
731      */
732     [DllImport(libname,
733        CharSet           = CharSet.Ansi,  // We want ANSI String
734        CallingConvention = CallingConvention.Cdecl)]
cli_free(int statement)735     internal static extern int cli_free(int statement);
736 
737     /*=====================================================================
738      * cli_commit
739      *     Commit current database transaction
740      * Parameters:
741      *     session - session descriptor as returned by cli_open
742      * Returns:
743      *     result code as described in cli_result_code enum
744      */
745     [DllImport(libname,
746        CharSet           = CharSet.Ansi,  // We want ANSI String
747        CallingConvention = CallingConvention.Cdecl)]
cli_commit(int session)748     internal static extern int cli_commit(int session);
749 
750     /*=====================================================================
751      * cli_precommit
752      *     Release all locks set by transaction. This methods allows other clients
753      *     to proceed, but it doesn't flush transaction to the disk.
754      * Parameters:
755      *     session - session descriptor as returned by cli_open
756      * Returns:
757      *     result code as described in cli_result_code enum
758      */
759     [DllImport(libname,
760        CharSet           = CharSet.Ansi,  // We want ANSI String
761        CallingConvention = CallingConvention.Cdecl)]
cli_precommit(int session)762     internal static extern int cli_precommit(int session);
763 
764     /*=====================================================================
765      * cli_abort
766      *     Abort current database transaction
767      * Parameters:
768      *     session - session descriptor as returned by cli_open
769      * Returns:
770      *     result code as described in cli_result_code enum
771      */
772     [DllImport(libname,
773        CharSet           = CharSet.Ansi,  // We want ANSI String
774        CallingConvention = CallingConvention.Cdecl)]
cli_abort(int session)775     internal static extern int cli_abort(int session);
776 
777     public enum FieldFlags: int {
778       cli_noindex       = 0, /* no indexes */
779       cli_hashed        = 1, /* field should be indexed usnig hash table */
780       cli_indexed       = 2  /* field should be indexed using B-Tree */
781     };
782 
783     [ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
784     internal struct CliFieldDescriptor {
785       public FieldType     type;
786       public FieldFlags    flags;
787       public IntPtr        name;
788       public IntPtr        refTableName;
789       public IntPtr        inverseRefFieldName;
790     };
791 
792     /*=====================================================================
793      * cli_describe
794      *     Describe fileds of specified table
795      * Parameters:
796      *     session - session descriptor as returned by cli_open
797      *     table   - name of the table
798      *     fields  - address of the pointer to the array of fields descriptors,
799      *               this array should be later deallocated by application by cli_free_memory()
800      * Returns:
801      *     >= 0 - number of fields in the table
802      *     < 0  - result code as described in cli_result_code enum
803      */
804     [DllImport(libname,
805        CharSet           = CharSet.Ansi,  // We want ANSI String
806        CallingConvention = CallingConvention.Cdecl)]
cli_describe( int session, string table, ref void* fields)807     internal static extern unsafe int cli_describe(
808       int    session,
809       string table,
810       ref void* fields);
811     //[In,Out] ref CliFieldDescriptor[] fields);  // cli_field_descriptor** fields
812 
813     /*=====================================================================
814      * cli_get_field_size
815      *     Calculate field size
816      * Parameters:
817      *     fields  - array with fields descriptors obtained using cli_describe function
818      *     field_no - number of the field
819      */
820     [DllImport(libname,
821        CharSet           = CharSet.Ansi,  // We want ANSI String
822        CallingConvention = CallingConvention.Cdecl)]
cli_get_field_size( [In, Out] CliFieldDescriptor[] fields, int field_no)823     internal static extern int cli_get_field_size(
824       [In, Out] CliFieldDescriptor[] fields,   // cli_field_descriptor* fields
825       int field_no);
826 
827     /*=====================================================================
828      * cli_get_field_offset
829      *     Calculate offset of the field
830      * Parameters:
831      *     fields  - array with fields descriptors obtained using cli_describe function
832      *     field_no - number of the field
833      */
834     [DllImport(libname,
835        CharSet           = CharSet.Ansi,  // We want ANSI String
836        CallingConvention = CallingConvention.Cdecl)]
cli_get_field_offset( [In, Out] CliFieldDescriptor[] fields, int field_no)837     internal static extern int cli_get_field_offset(
838       [In, Out] CliFieldDescriptor[] fields,   // cli_field_descriptor* fields
839       int field_no);
840 
841     [ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
842       internal struct CliTableDescriptor {
843       public IntPtr name;
844     }
845 
846     /*=====================================================================
847      * cli_show_tables
848      *     Show all tables of specified database
849      * Parameters:
850      *     session - session descriptor as returned by cli_open
851      *     tables  - address of the pointer to the array of tables descriptors,
852      *               this array should be later deallocated by application by cli_free_memory()
853      * Returns:
854      *     >= 0 - number of tables in the database (Metatable is not returned/counted)
855      *     < 0  - result code as described in cli_result_code enum
856      */
857     [DllImport(libname,
858        CharSet           = CharSet.Ansi,  // We want ANSI String
859        CallingConvention = CallingConvention.Cdecl)]
cli_show_tables( int session, ref IntPtr tables)860     internal static extern int cli_show_tables(
861       int session,
862       //[In, Out] CliTableDescriptor[] tables
863       ref IntPtr tables);   // cli_table_descriptor** tables
864 
865     /*=====================================================================
866      * cli_create_table
867      *     Create new table
868      * Parameters:
869      *     session   - session descriptor as returned by cli_open
870      *     tableName - name of new table
871      *     nFields   - number of columns in the table
872      *     fields    - array with table columns descriptors
873      * Returns:
874      *     result code as described in cli_result_code enum
875      */
876     [DllImport(libname,
877        CharSet           = CharSet.Ansi,  // We want ANSI String
878        CallingConvention = CallingConvention.Cdecl)]
cli_create_table( int session, string tableName, int nFields, [In, Out] CliFieldDescriptor[] fields)879     internal static extern int cli_create_table(
880       int       session,
881       string    tableName,
882       int       nFields,
883       [In, Out] CliFieldDescriptor[] fields);  // cli_field_descriptor* fields
884 
885     /*=====================================================================
886      * cli_alter_table
887      *     Change table format
888      * Parameters:
889      *     session   - session descriptor as returned by cli_open
890      *     tableName - name of existing table
891      *     nFields   - number of columns in the table
892      *     fields    - array with new table columns descriptors
893      * Returns:
894      *     result code as described in cli_result_code enum
895      */
896     [DllImport(libname,
897        CharSet           = CharSet.Ansi,  // We want ANSI String
898        CallingConvention = CallingConvention.Cdecl)]
cli_alter_table( int session, string tableName, int nFields, [MarshalAs(UnmanagedType.LPArray)] CliFieldDescriptor[] fields)899     internal static extern int cli_alter_table(
900       int    session,
901       string tableName,
902       int    nFields,
903       [MarshalAs(UnmanagedType.LPArray)]
904       CliFieldDescriptor[] fields);  // cli_field_descriptor* fields);
905 
906     /*=====================================================================
907      * cli_drop_table
908      *     drop the table
909      * Parameters:
910      *     session   - session descriptor as returned by cli_open
911      *     tableName - name of deleted table
912      * Returns:
913      *     result code as described in cli_result_code enum
914      */
915     [DllImport(libname,
916        CharSet           = CharSet.Ansi,  // We want ANSI String
917        CallingConvention = CallingConvention.Cdecl)]
cli_drop_table(int session, string tableName)918     internal static extern int cli_drop_table(int session, string tableName);
919 
920 
921     /*=====================================================================
922      * cli_alter_index
923      *     add or remove column index
924      * Parameters:
925      *     session   - session descriptor as returned by cli_open
926      *     tableName - name of the table
927      *     fieldName - name of field
928      *     newFlags  - new flags of the field, if index exists for this field, but is not specified in
929      *                 <code>newFlags</code> mask, then it will be removed; if index not exists, but is
930      *                 specified in <code>newFlags</code> mask, then it will be created. *
931      * Returns:
932      *     result code as described in cli_result_code enum
933      */
934     [DllImport(libname,
935        CharSet           = CharSet.Ansi,  // We want ANSI String
936        CallingConvention = CallingConvention.Cdecl)]
cli_alter_index( int session, string tableName, string fieldName, FieldFlags newFlags)937     internal static extern int cli_alter_index(
938       int session, string tableName, string fieldName,
939       FieldFlags newFlags);
940 
941     /*=====================================================================
942      * cli_set_error_handler
943      *     Set GigaBASE error handler. Handler should be no-return function which perform stack unwind.
944      * Parameters:
945      *     session   - session descriptor as returned by cli_open
946      *     handler   - error handler
947      * Returns:
948      *     previous handler
949      */
950      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
CliErrorHandler(int error, [MarshalAs(UnmanagedType.LPStr)] string msg, int msgarg, IntPtr context)951     public delegate void CliErrorHandler(int error,
952       [MarshalAs(UnmanagedType.LPStr)] string msg, int msgarg, IntPtr context);
953 
954     [DllImport(libname,
955        CharSet           = CharSet.Ansi,  // We want ANSI String
956        CallingConvention = CallingConvention.Cdecl)]
cli_set_error_handler(int session, CliErrorHandler new_handler, IntPtr context)957     internal static extern CliErrorHandler cli_set_error_handler(int session, CliErrorHandler new_handler, IntPtr context);
958 
959     /*=====================================================================
960      * cli_freeze
961      *    Freeze cursor. Make it possible to reused cursor after commit of the current transaction.
962      * Parameters:
963      *     statement   - statememt descriptor returned by cli_statement
964      * Returns:
965      *     result code as described in cli_result_code enum
966      */
967     [DllImport(libname,
968        CharSet           = CharSet.Ansi,  // We want ANSI String
969        CallingConvention = CallingConvention.Cdecl)]
cli_freeze(int statement)970     internal static extern int cli_freeze(int statement);
971 
972     /*=====================================================================
973      * cli_unfreeze
974      *    Unfreeze cursor. Reuse previously frozen cursor.
975      * Parameters:
976      *     statement   - statememt descriptor returned by cli_statement
977      * Returns:
978      *     result code as described in cli_result_code enum
979      */
980     [DllImport(libname,
981        CharSet           = CharSet.Ansi,  // We want ANSI String
982        CallingConvention = CallingConvention.Cdecl)]
cli_unfreeze(int statement)983     internal static extern int cli_unfreeze(int statement);
984 
985 
986     /*=====================================================================
987      * cli_attach
988      *    Attach thread to the database. Each thread except one opened the database should first
989      *    attach to the database before any access to the database, and detach after end of the work with database
990      * Parameters:
991      *     session - session descriptor returned by cli_open
992      * Returns:
993      *     result code as described in cli_result_code enum
994      */
995     [DllImport(libname,
996        CharSet           = CharSet.Ansi,  // We want ANSI String
997        CallingConvention = CallingConvention.Cdecl)]
cli_attach(int session)998     internal static extern int cli_attach(int session);
999 
1000     /*=====================================================================
1001      * cli_detach
1002      *    Detach thread from the database. Each thread except one opened the database should perform
1003      *    attach to the database before any access to the database, and detach after end of the work with database
1004      * Parameters:
1005      *     session - session descriptor returned by cli_open
1006      *     detach_mode - bit mask representing detach mode
1007      * Returns:
1008      *     result code as described in cli_result_code enum
1009      */
1010     [Flags]
1011       public enum CliDetachMode : int {
1012       cli_commit_on_detach          = 1,
1013       cli_destroy_context_on_detach = 2
1014     };
1015 
1016     [DllImport(libname,
1017        CharSet           = CharSet.Ansi,  // We want ANSI String
1018        CallingConvention = CallingConvention.Cdecl)]
cli_detach(int session, CliDetachMode detach_mode)1019     internal static extern int cli_detach(int session, CliDetachMode detach_mode);
1020 
1021 
1022     /*=====================================================================
1023      * cli_free_memory
1024      *    Free memory allocated by cli_show_tables and cli_describe
1025      * Parameters:
1026      *     session - session descriptor returned by cli_open
1027      *     ptr - pointer to the allocated buffer
1028      */
1029     [DllImport(libname,
1030        CharSet           = CharSet.Ansi,  // We want ANSI String
1031        CallingConvention = CallingConvention.Cdecl)]
cli_free_memory(int session, void* ptr)1032     internal static extern unsafe void cli_free_memory(int session, void* ptr);
1033 
1034     [ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
1035       public struct CliDatabaseMonitor {
1036       public int n_readers;
1037       public int n_writers;
1038       public int n_blocked_readers;
1039       public int n_blocked_writers;
1040       public int n_users;
1041     };
1042 
1043     /*=====================================================================
1044      * cli_get_database_state
1045      *    Obtain information about current state of the database
1046      * Parameters:
1047      *     session - session descriptor returned by cli_open
1048      *     monitor - pointer to the monitor structure. The folloing fields are set:
1049      *       n_readers: number of granted shared locks
1050      *       n_writers: number of granted exclusive locks
1051      *       n_blocked_reader: number of threads which shared lock request was blocked
1052      *       n_blocked_writers: number of threads which exclusive lock request was blocked
1053      *       n_users: number of processes openned the database
1054      * Returns:
1055      *     result code as described in cli_result_code enum
1056      */
1057     [DllImport(libname,
1058        CharSet           = CharSet.Ansi,  // We want ANSI String
1059        CallingConvention = CallingConvention.Cdecl)]
cli_get_database_state(int session, ref CliDatabaseMonitor monitor)1060     internal static extern int cli_get_database_state(int session, ref CliDatabaseMonitor monitor);
1061 
1062     /*=====================================================================
1063      * cli_set_trace_function
1064      *    Set trace function which will be used to output GigaBASE trace messages
1065      * Parameters:
1066      *     func - pointer to trace function which receives trace message terminated with new line character
1067      */
1068      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
CliTraceFunction(string msg)1069     public delegate void CliTraceFunction(string msg);
1070 
1071     [DllImport(libname,
1072        CharSet           = CharSet.Ansi,  // We want ANSI String
1073        CallingConvention = CallingConvention.Cdecl)]
cli_set_trace_function(CliTraceFunction func)1074     internal static extern void cli_set_trace_function(CliTraceFunction func);
1075 
1076     /*=====================================================================
1077      * cli_prepare_query
1078      *     Prepare SubSQL query statement.
1079      * Parameters:
1080      *     session - session descriptor returned by cli_open
1081      *     query   - query string with optional parameters. Parameters are specified
1082      *               as '%T' where T is one or two character code of parameter type using the same notation
1083      *               as in printf: %d or %i - int, %f - float or double, %ld - int8, %s - string, %p - oid...
1084      * Returns:
1085      *     >= 0 - statement descriptor
1086      *     <  0 - error code as described in cli_result_code enum
1087      */
1088     [DllImport(libname,
1089        CharSet           = CharSet.Ansi,  // We want ANSI String
1090        CallingConvention = CallingConvention.Cdecl)]
cli_prepare_query(int session, string query)1091     internal static extern int cli_prepare_query(int session, string query);
1092 
1093     /*
1094      * cli_execute_query
1095      *     Execute query previously prepared by cli_prepare_query
1096      * Parameters:
1097      *     statement - statement descriptor returned by cli_prepare_query
1098      *     for_update - not zero if fetched rows will be updated
1099      *     record_struct - structure to receive selected record fields
1100      *     ...     - varying list of query parameters
1101      * Returns:
1102      *     >= 0 - success, for select statements number of fetched rows is returned
1103      *     <  0 - error code as described in cli_result_code enum
1104      */
1105     [DllImport(libname,
1106        CharSet           = CharSet.Ansi,  // We want ANSI String
1107        CallingConvention = CallingConvention.Cdecl)]
cli_execute_query( int statement, QueryType queryType, IntPtr record_struct, params object[] list)1108     internal static extern int cli_execute_query(
1109       int          statement,
1110       QueryType    queryType,
1111       IntPtr       record_struct, // void*
1112       params object[] list);
1113 
1114     /*
1115      * cli_insert_struct
1116      *     Insert new record represented as C structure
1117      * Parameters:
1118      *     session - session descriptor returned by cli_open
1119      *     table_name - name of the destination table
1120      *     record_struct - structure specifying value of record fields
1121      *     oid - pointer to the location to receive OID of created record (may be NULL)
1122      * Returns:
1123      *     result code as described in cli_result_code enum
1124      */
1125     [DllImport(libname,
1126        CharSet           = CharSet.Ansi,  // We want ANSI String
1127        CallingConvention = CallingConvention.Cdecl)]
cli_insert_struct( int session, string table_name, IntPtr record_struct, ref uint oid)1128     internal static extern int cli_insert_struct(
1129       int session,
1130       string table_name,
1131       IntPtr record_struct, // void*
1132       ref uint oid);
1133 
1134 
1135     /**
1136      * cli_lock
1137      *     Set exclusive database lock
1138      * Parameters:
1139      *     session - session descriptor returned by cli_open
1140      * Returns:
1141      *     result code as described in cli_result_code enum
1142      */
1143     [DllImport(libname,
1144        CharSet           = CharSet.Ansi,  // We want ANSI String
1145        CallingConvention = CallingConvention.Cdecl)]
cli_lock(int session)1146     internal static extern int cli_lock(int session);
1147 
1148     /**
1149      * cli_backup
1150      *     Perform database backup
1151      * Parameters:
1152      *     session - session descriptor returned by cli_open
1153      *     file_name - backup file name
1154      *     compatify - if true then databae will be compactified during backup -
1155      *                 i.e. all used objects will be placed together without holes; if false then
1156      *                 backup is performed by just writting memory mapped object to the backup file.
1157      * Returns:
1158      *     result code as described in cli_result_code enum
1159      */
1160     [DllImport(libname,
1161        CharSet           = CharSet.Ansi,  // We want ANSI String
1162        CallingConvention = CallingConvention.Cdecl)]
cli_backup(int session, string file_name, int compactify)1163     internal static extern int cli_backup(int session, string file_name, int compactify);
1164 
1165     /**
1166      * cli_backup
1167      *     Schedule database backup
1168      * Parameters:
1169      *     session - session descriptor returned by cli_open
1170      *     file_name -  path to backup file. If name ends with '?', then
1171      *                  each backup willbe placed in seprate file with '?' replaced with current timestamp
1172      *     period - period of performing backups in seconds
1173      * Returns:
1174      *     result code as described in cli_result_code enum
1175      */
1176     [DllImport(libname,
1177        CharSet           = CharSet.Ansi,  // We want ANSI String
1178        CallingConvention = CallingConvention.Cdecl)]
cli_schedule_backup(int session, string file_name, int period)1179     internal static extern int cli_schedule_backup(int session, string file_name, int period);
1180   }
1181 }
1182