About Monkey 2 › Forums › Monkey 2 Projects › WIP NetDB (Database) Module: Need Feedback
This topic contains 3 replies, has 2 voices, and was last updated by
scurty 1 year, 10 months ago.
-
AuthorPosts
-
May 30, 2017 at 3:21 pm #8387
Taking influence from PHP and using the amazingness of MX2 I’ve updated my previous WIP SQLite3 Abstraction Layer into using JSON instead of a Stack< StringMap< String > >
Again still, the goal here is to execute very simple SQL Queries and get the Results from native MX2. (Now Using Json for the Return Values)
The following Code Sample shows how it’s done as of now. (Subject to change due to possible future enhancements)
Monkey1234567891011121314151617181920212223#Import "<std>"#Import "netdb"Using std..Using netdb..Function Main()Local DB:Database = New Database("newdb.sqlite3")If(DB.Open())Local results:JsonObject = DB.Query( AppArgs()[1] )' Print First RowLocal first_row := results.GetObject("1") ' Get the row objectPrint first_row.GetString("b") ' get the needed value from said rowPrint results.ToJson() ' print the whole json result as a stringDB.Close()EndifEndThe “netdb.monkey2” Module is Here, you should be able to just be plug and play into your projects.
(Tested only on Windows 10 & Linux Kernel 4+)
I wrote this with barely any documentation very quickly so forgive any memory leaks or flat-out wrong usage of the sqlite3 lib. x’D Please you’re welcome to suggest any improvements.Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130#Import "<std>"#Import "<sqlite>"Namespace netdbUsing sqlite..Using std..' --- Abstraction layer for a Simple Database ---Class DatabaseField db:sqlite3 PtrField res:sqlite3_stmt PtrField Name:StringMethod New(name:String)Self.Name = nameEnd' If a database exists, load it, otherwise, create it. Returns if the database was loaded or notMethod Open:Bool()Local success:Bool = FalseIf( sqlite3_open( Self.Name, Varptr db ) = SQLITE_OK )success = TrueElsePrint "Failed to Open Database - "+sqlite3_errmsg( db )sqlite3_close( db )EndifReturn successEnd' Closes the databaseMethod Close()sqlite3_close( db )End' A simple way of sending queries to the databases and getting the resultsMethod Query:JsonObject(data:String)Local rowsobj:JsonObject = New JsonObject' - Check Query StringPrint "Validating Query..."If(sqlite3_prepare_v2( db, data, -1, Varptr res, Null) = SQLITE_OK)Local colnum:Int = sqlite3_column_count(res) ' Get Result CountLocal rownum:Int = 0While(True) ' - LoopIf(sqlite3_step( res ) = SQLITE_ROW ) ' If there's a RowLocal print_string:String = "" ' Debug Output' Create New Row in JsonLocal row_id:String = Cast<String>(rownum) ' Get Row String IDrowsobj[row_id] = New JsonObject ' Create New Row from String IDLocal newrow := rowsobj.GetObject(row_id) ' Get New Row Ref' Generate RowsFor Local i:Int = 0 Until colnumLocal typeint := sqlite3_column_type( res, i ) ' Get Type of EntryLocal colname := sqlite3_column_name( res, i ) ' Get Column NameSelect typeint ' Determine the Correct Data TypeCase 1 ' ADD INTEGER COLUMNLocal colval:Int = sqlite3_column_int( res, i )newrow.SetNumber(colname, colval)print_string += "INTEGER:" + colname + " " + colval + " | "Case 2 ' ADD FLOAT/REAL COLUMNLocal colval:Double = sqlite3_column_double( res, i )newrow.SetNumber(colname, colval)print_string += "REAL:" + colname + " " + colval + " | "Case 3 ' ADD STRING/TEXT COLUMNLocal colval := sqlite3_column_text( res, i )newrow.SetString(colname, colval)print_string += "TEXT:" + colname + " " + colval + " | "Case 4 ' ADD BLOB/ARRAY? COLUMN (Probably coming soon)'Local colval := sqlite3_column_blob( res, i )'print_string += "BLOB:" + colname + " " + colval + " | "Default ' NOT AN ACCEPTABLE TYPE FOR NOWprint_string += "UNKNOWN TYPE"End SelectNextPrint print_stringrownum += 1ElseExit ' - Exit Read Row LoopEndWendPrint "Query Finished."Else ' - On Failed Query PreparationPrint "Failed to Prepare Query - "+sqlite3_errmsg( db )sqlite3_close( db ) ' Close sql fileEndifsqlite3_finalize( res ) ' Clean up stmt?Return rowsobjEndEnd ClassNow you can use the Json Library for transmitting query results over TCP/UDP protocols, to kinda make your own storage server if you wish.
Note: This Module doesn’t support arrays as database results just yet, A.K.A Blobs in SQLite3 “speak” I think.
The next improvement should be arrays, and maybe better access to structured table return types. But that should be simple to implement yourself if needed.
June 6, 2017 at 7:58 am #8489Very nice!
June 9, 2017 at 9:24 pm #8539Thanks Mark!
Should I switch to JSON for the result Data instead of making the Alias?
I feel like it would be more flexible since you can use GetString/GetNumber instead of type casting.Edit: The only issue I see with JSON is generating the results from the Database would probably require parsing the JSON from an assembled string, that might add too much overhead for response times. I’ll try and run a few tests. Update later.
June 11, 2017 at 11:16 pm #8625Updated to JSON. Works great! Probably faster than my own parsing functions! I still have both versions. I’ll compare, but I’m very sure that JSON is quicker and more reliable. (Sorry for the double post)
-
AuthorPosts
You must be logged in to reply to this topic.