class QuickBase::Client
QuickBase
Client: Ruby wrapper class for QuickBase
HTTP API. The class’s method and member variable names correspond closely to the QuickBase
HTTP API reference. This class was written using ruby 1.8.6. It is strongly recommended that you use ruby 1.9.2 or higher. Use REXML
to process any QuickBase
response XML not handled by this class. The main work of this class is done in initialize(), sendRequest(), and processResponse(). The API_ wrapper methods just set things up for sendRequest() and put values from the response into member variables.
Attributes
Public Class Methods
Class method to create an instance of QuickBase::Client
using a Hash of parameters. E.g. qbc = QuickBase::Client.init
( { “stopOnError” => true, “printRequestsAndResponses” => true } )
# File lib/QuickBaseClient.rb, line 127 def Client.init( options ) options ||= {} options["useSSL"] ||= true options["printRequestsAndResponses"] ||= false options["stopOnError"] ||= false options["showTrace"] ||= false options["org"] ||= "www" options["debugHTTPConnection"] ||= false options["domain"] ||= "quickbase" options["proxy_options"] ||= nil instance = Client.new( options["username"], options["password"], options["appname"], options["useSSL"], options["printRequestsAndResponses"], options["stopOnError"], options["showTrace"], options["org"], options["apptoken"], options["debugHTTPConnection"], options["domain"], options["proxy_options"]) end
Set printRequestsAndResponses to true to view the XML sent to QuickBase
and return from QuickBase
. This can be very useful during debugging.
Set stopOnError to true to discontinue sending requests to QuickBase
after an error has occured with a request. Set showTrace to true to view the complete stack trace of your running program. This should only be necessary as a last resort when a low-level exception has occurred.
To create an instance of QuickBase::Client
using a Hash of options, use QuickBase::Client.init(options)
instead of QuickBase::Client.new()
# File lib/QuickBaseClient.rb, line 84 def initialize( username = nil, password = nil, appname = nil, useSSL = true, printRequestsAndResponses = false, stopOnError = false, showTrace = false, org = "www", apptoken = nil, debugHTTPConnection = false, domain = "quickbase", proxy_options = nil ) begin @org = org ? org : "www" @domain = domain ? domain : "quickbase" @apptoken = apptoken @printRequestsAndResponses = printRequestsAndResponses @stopOnError = stopOnError @escapeBR = @ignoreCR = @ignoreLF = @ignoreTAB = true toggleTraceInfo( showTrace ) if showTrace setHTTPConnectionAndqbhost( useSSL, org, domain, proxy_options ) debugHTTPConnection() if debugHTTPConnection @standardRequestHeaders = { "Content-Type" => "application/xml" } if username and password authenticate( username, password ) if appname and @errcode == "0" findDBByname( appname ) if @dbid and @errcode == "0" getDBInfo( @dbid ) getSchema( @dbid ) end end end rescue Net::HTTPBadRequest => @lastError rescue Net::HTTPBadResponse => @lastError rescue Net::HTTPHeaderSyntaxError => @lastError rescue StandardError => @lastError end end
-
creates a
QuickBase::Client
, -
signs into
QuickBase
-
connects to a specific application
-
runs code in the associated block
-
signs out of
QuickBase
e.g. QuickBase::Client.processDatabase
( “user”, “password”, “my DB” ) { |qbClient,dbid| qbClient.getDBInfo
( dbid ) }
# File lib/QuickBaseClient.rb, line 3164 def Client.processDatabase( username, password, appname, chainAPIcalls = nil ) if username and password and appname and block_given? begin qbClient = Client.new( username, password, appname ) @chainAPIcalls = chainAPIcalls yield qbClient, qbClient.dbid rescue StandardError ensure qbClient.signOut @chainAPIcalls = nil end end end
Public Instance Methods
API_AddField, using the active table id.
# File lib/QuickBaseClient.rb, line 1674 def _addField( label, type, mode = nil ) addField( @dbid, label, type, mode ) end
API_AddRecord, using the active table id.
# File lib/QuickBaseClient.rb, line 1703 def _addRecord( fvlist = nil, disprec = nil, fform = nil, ignoreError = nil, update_id = nil ) addRecord( @dbid, fvlist, disprec, fform, ignoreError, update_id ) end
API_AddReplaceDBPage, using the active table id.
# File lib/QuickBaseClient.rb, line 1734 def _addReplaceDBPage( *args ) addReplaceDBPage( @dbid, args ) end
API_AddUserToRole, using the active table id.
# File lib/QuickBaseClient.rb, line 1764 def _addUserToRole( userid, roleid ) addUserToRole( @dbid, userid, roleid ) end
API_ChangePermission (appears to be deprecated), using the active table id.
# File lib/QuickBaseClient.rb, line 1909 def _changePermission( *args ) changePermission( @dbid, args ) end
API_ChangeRecordOwner
# File lib/QuickBaseClient.rb, line 1927 def _changeRecordOwner( rid, newowner ) changeRecordOwner( @dbid, rid, newowner ) end
API_ChangeUserRole, using the active table id.
# File lib/QuickBaseClient.rb, line 1944 def _changeUserRole( userid, roleid, newroleid ) changeUserRole( @dbid, userid, roleid, newroleid ) end
# File lib/QuickBaseClient.rb, line 636 def _childElementsAsString() childElementsAsString( @qdbapi ) end
API_CloneDatabase, using the active table id.
# File lib/QuickBaseClient.rb, line 1969 def _cloneDatabase( *args ) cloneDatabase( @dbid, args ) end
API_CopyMasterDetail, using the active table id.
# File lib/QuickBaseClient.rb, line 1994 def _copyMasterDetail( *args ) copyMasterDetail( @dbid, args ) end
API_DeleteDatabase, using the active table id.
# File lib/QuickBaseClient.rb, line 2044 def _deleteDatabase() deleteDatabase( @dbid ) end
API_DeleteField, using the active table id.
# File lib/QuickBaseClient.rb, line 2058 def _deleteField( fid ) deleteField( @dbid, fid ) end
Delete a field, using its name instead of its id. Uses the active table id.
# File lib/QuickBaseClient.rb, line 2061 def _deleteFieldName( fieldName ) if @dbid and @fields @fid = lookupFieldIDByName( fieldName ) if @fid deleteField( @dbid, @fid ) end end nil end
API_DeleteRecord, using the active table id.
# File lib/QuickBaseClient.rb, line 2083 def _deleteRecord( rid ) deleteRecord( @dbid, rid ) end
API_DoQuery, using the active table id.
# File lib/QuickBaseClient.rb, line 2130 def _doQuery( *args ) doQuery( @dbid, args ) end
API_DoQueryCount, using the active table id.
# File lib/QuickBaseClient.rb, line 2166 def _doQueryCount( query ) doQueryCount( @dbid, query ) end
version of doQuery that takes a Hash of parameters
# File lib/QuickBaseClient.rb, line 2136 def _doQueryHash( doQueryOptions ) doQueryOptions ||= {} raise "options must be a Hash" unless doQueryOptions.is_a?(Hash) doQueryOptions["dbid"] ||= @dbid doQueryOptions["fmt"] ||= "structured" doQuery( doQueryOptions["dbid"], doQueryOptions["query"], doQueryOptions["qid"], doQueryOptions["qname"], doQueryOptions["clist"], doQueryOptions["slist"], doQueryOptions["fmt"], doQueryOptions["options"] ) end
Runs API_DoQuery using the name of a query. Uses the active table id .
# File lib/QuickBaseClient.rb, line 2133 def _doQueryName( queryName ) doQuery( @dbid, nil, nil, queryName ) end
Download a file’s contents from a file attachment field in QuickBase
. You must write the contents to disk before a local file exists. Uses the active table id.
# File lib/QuickBaseClient.rb, line 2218 def _downLoadFile( rid, fid, vid = "0" ) downLoadFile( @dbid, rid, fid, vid ) end
API_EditRecord, using the active table id.
# File lib/QuickBaseClient.rb, line 2266 def _editRecord( *args ) editRecord( @dbid, args ) end
API_FieldAddChoices, using the active table id.
# File lib/QuickBaseClient.rb, line 2293 def _fieldAddChoices( fid, choice ) fieldAddChoices( @dbid, fid, choice ) end
Runs API_FieldAddChoices using a field name instead ofa field id. Uses the active table id. Expects getSchema to have been run.
# File lib/QuickBaseClient.rb, line 2297 def _fieldNameAddChoices( fieldName, choice ) if fieldName and choice and @fields @fid = lookupFieldIDByName( fieldName ) fieldAddChoices( @dbid, @fid, choice ) end nil end
Runs API_FieldRemoveChoices using a field name instead of a field id. Uses the active table id.
# File lib/QuickBaseClient.rb, line 2333 def _fieldNameRemoveChoices( fieldName, choice ) if fieldName and choice and @fields @fid = lookupFieldIDByName( fieldName ) fieldRemoveChoices( @dbid, @fid, choice ) end nil end
API_FieldRemoveChoices, using the active table id.
# File lib/QuickBaseClient.rb, line 2330 def _fieldRemoveChoices( fid, choice ) fieldRemoveChoices( @dbid, fid, choice ) end
API_GenAddRecordForm, using the active table id.
# File lib/QuickBaseClient.rb, line 2372 def _genAddRecordForm( fvlist = nil ) genAddRecordForm( @dbid, fvlist ) end
API_GenResultsTable, using the active table id.
# File lib/QuickBaseClient.rb, line 2398 def _genResultsTable( *args ) genResultsTable( @dbid, args ) end
# File lib/QuickBaseClient.rb, line 2414 def _getAncestorInfo() getAncestorInfo(@dbid) end
API_GetAppDTMInfo, using the active table id.
# File lib/QuickBaseClient.rb, line 2440 def _getAppDTMInfo() getAppDTMInfo( @dbid ) end
API_GetBillingStatus, using the active table id.
# File lib/QuickBaseClient.rb, line 2456 def _getBillingStatus() getBillingStatus(@dbid) end
API_GetDBInfo, using the active table id.
# File lib/QuickBaseClient.rb, line 2479 def _getDBInfo() getDBInfo( @dbid ) end
API_GetDBPage, using the active table id.
# File lib/QuickBaseClient.rb, line 2504 def _getDBPage( pageid, pagename = nil ) getDBPage( @dbid, pageid, pagename ) end
API_GetDBVar, using the active table id.
# File lib/QuickBaseClient.rb, line 2521 def _getDBvar( varname ) getDBvar( @dbid, varname ) end
API_GetEntitlementValues, using the active table id.
# File lib/QuickBaseClient.rb, line 2542 def _getEntitlementValues() getEntitlementValues( @dbid ) end
API_GetFileAttachmentUsage, using the active table id.
# File lib/QuickBaseClient.rb, line 2560 def _getFileAttachmentUsage() getFileAttachmentUsage( @dbid ) end
API_GetNumRecords, using the active table id.
# File lib/QuickBaseClient.rb, line 2574 def _getNumRecords() getNumRecords( @dbid ) end
API_GetRecordAsHTML, using the active table id.
# File lib/QuickBaseClient.rb, line 2618 def _getRecordAsHTML( rid, jht = nil, dfid = nil ) getRecordAsHTML( @dbid, rid, jht, dfid ) end
API_GetRecordInfo, using the active table id.
# File lib/QuickBaseClient.rb, line 2644 def _getRecordInfo( rid = @rid ) getRecordInfo( @dbid, rid ) end
API_GetRoleInfo, using the active table id.
# File lib/QuickBaseClient.rb, line 2670 def _getRoleInfo() getRoleInfo( @dbid ) end
API_GetSchema, using the active table id.
# File lib/QuickBaseClient.rb, line 2704 def _getSchema() getSchema( @dbid ) end
API_GetUserRole, using the active table id.
# File lib/QuickBaseClient.rb, line 2782 def _getUserRole( userid, inclgrps = nil ) getUserRole( @dbid, userid, inclgrps ) end
API_ImportFromCSV, using the active table id.
# File lib/QuickBaseClient.rb, line 2838 def _importFromCSV( *args ) importFromCSV( @dbid, args ) end
Import data directly from an Excel file into the active table.
# File lib/QuickBaseClient.rb, line 4387 def _importFromExcel(excelFilename,lastColumn = 'j',lastDataRow = 0,worksheetNumber = 1,fieldNameRow = 1,firstDataRow = 2,firstColumn = 'a') importFromExcel( @dbid, excelFilename, lastColumn, lastDataRow, worksheetNumber, fieldNameRow, firstDataRow, firstColumn ) end
API_ListDBPages, using the active table id.
# File lib/QuickBaseClient.rb, line 2868 def _listDBPages() listDBPages(@dbid) end
# File lib/QuickBaseClient.rb, line 609 def _printChildElements() printChildElements( @qdbapi ) end
API_ProvisionUser, using the active table id.
# File lib/QuickBaseClient.rb, line 2888 def _provisionUser( roleid, email, fname, lname ) provisionUser( @dbid, roleid, email, fname, lname ) end
API_PurgeRecords, using the active table id.
# File lib/QuickBaseClient.rb, line 2902 def _purgeRecords( query = nil, qid = nil, qname = nil ) purgeRecords( @dbid, query, qid, qname ) end
Remove the file from a File Attachment field in an existing record in the active table e.g. _removeFileAttachment( “6”, “Document” )
# File lib/QuickBaseClient.rb, line 4640 def _removeFileAttachment( rid , fileAttachmentFieldName ) updateFile( @dbid, rid, "delete", fileAttachmentFieldName ) end
API_RemoveUserFromRole, using the active table id.
# File lib/QuickBaseClient.rb, line 2918 def _removeUserFromRole( userid, roleid ) removeUserFromRole( @dbid, userid, roleid ) end
API_RenameApp, using the active table id.
# File lib/QuickBaseClient.rb, line 2933 def _renameApp( newappname ) renameApp( @dbid, newappname ) end
API_RunImport, using the active table id.
# File lib/QuickBaseClient.rb, line 2948 def _runImport( id ) runImport( @dbid, id ) end
API_SendInvitation, using the active table id.
# File lib/QuickBaseClient.rb, line 2964 def _sendInvitation( userid, usertext = "Welcome to my application!" ) sendInvitation( @dbid, userid, usertext ) end
# File lib/QuickBaseClient.rb, line 3209 def _setActiveRecord( rid ) setActiveRecord( @dbid, rid ) end
API_SetAppData, using the active table id.
# File lib/QuickBaseClient.rb, line 2979 def _setAppData( appdata ) setAppData( @dbid, appdata ) end
API_SetDBvar, using the active table id.
# File lib/QuickBaseClient.rb, line 2995 def _setDBvar( varname, value ) setDBvar( @dbid, varname, value ) end
API_SetFieldProperties, using the active table id.
# File lib/QuickBaseClient.rb, line 3024 def _setFieldProperties( properties, fid ) setFieldProperties( @dbid, properties, fid ) end
API_SetKeyField, using the active table id.
# File lib/QuickBaseClient.rb, line 3039 def _setKeyField(fid) setKeyField( @dbid, fid ) end
Update the file attachment in an existing record in the active record in the active table. e.g. _updateFile( “contacts.txt”, “Contacts File” )
# File lib/QuickBaseClient.rb, line 4628 def _updateFile( filename, fileAttachmentFieldName ) updateFile( @dbid, @rid, filename, fileAttachmentFieldName ) end
Upload a file into a new record in the active table. e.g. uploadFile( “contacts.txt”, “Contacts File” )
# File lib/QuickBaseClient.rb, line 4600 def _uploadFile( filename, fileAttachmentFieldName ) uploadFile( @dbid, filename, fileAttachmentFieldName ) end
API_UserRoles, using the active table id.
# File lib/QuickBaseClient.rb, line 3080 def _userRoles() userRoles( @dbid ) end
API_AddField
# File lib/QuickBaseClient.rb, line 1653 def addField( dbid, label, type, mode = nil ) @dbid, @label, @type, @mode = dbid, label, type, mode if isValidFieldType?( type ) xmlRequestData = toXML( :label, @label ) + toXML( :type, @type ) xmlRequestData << toXML( :mode, mode ) if mode sendRequest( :addField, xmlRequestData ) @fid = getResponseValue( :fid ) @label = getResponseValue( :label ) return self if @chainAPIcalls return @fid, @label else raise "addField: Invalid field type '#{type}'. Valid types are " + @validFieldTypes.join( "," ) end end
Adds a field value to the list of fields to be set by the next addRecord() or editRecord() call to QuickBase
.
-
name: label of the field value to be set.
-
fid: id of the field to be set.
-
filename: if the field is a file attachment field, the name of the file that should be displayed in
QuickBase
. -
value: the value to set in this field. If the field is a file attachment field, the name of the file that should be uploaded into
QuickBase
.
# File lib/QuickBaseClient.rb, line 1164 def addFieldValuePair( name, fid, filename, value ) @fvlist ||= [] @fvlist << FieldValuePairXML.new( self, name, fid, filename, value ).to_s @fvlist end
Use this if you aren’t sure whether a particular record already exists or not
# File lib/QuickBaseClient.rb, line 3091 def addOrEditRecord( dbid, fvlist, rid = nil, disprec = nil, fform = nil, ignoreError = nil, update_id = nil, key = nil ) if rid or key record = editRecord( dbid, rid, fvlist, disprec, fform, ignoreError, update_id, key ) if !@requestSucceeded addRecord( dbid, fvlist, disprec, fform, ignoreError, update_id ) end record else addRecord( dbid, fvlist, disprec, fform, ignoreError, update_id ) end end
API_AddRecord
# File lib/QuickBaseClient.rb, line 1677 def addRecord( dbid, fvlist = nil, disprec = nil, fform = nil, ignoreError = nil, update_id = nil, msInUTC =nil ) @dbid, @fvlist, @disprec, @fform, @ignoreError, @update_id, @msInUTC = dbid, fvlist, disprec, fform, ignoreError, update_id, msInUTC setFieldValues( fvlist, false ) if fvlist.is_a?(Hash) xmlRequestData = "" if @fvlist and @fvlist.length > 0 @fvlist.each{ |fv| xmlRequestData << fv } #see addFieldValuePair, clearFieldValuePairList, @fvlist end xmlRequestData << toXML( :disprec, @disprec ) if @disprec xmlRequestData << toXML( :fform, @fform ) if @fform xmlRequestData << toXML( :ignoreError, "1" ) if @ignoreError xmlRequestData << toXML( :update_id, @update_id ) if @update_id xmlRequestData << toXML( :msInUTC, "1" ) if @msInUTC xmlRequestData = nil if xmlRequestData.length == 0 sendRequest( :addRecord, xmlRequestData ) @rid = getResponseValue( :rid ) @update_id = getResponseValue( :update_id ) return self if @chainAPIcalls return @rid, @update_id end
API_AddReplaceDBPage
# File lib/QuickBaseClient.rb, line 1708 def addReplaceDBPage( dbid, pageid, pagename, pagetype, pagebody, ignoreError = nil ) @dbid, @pageid, @pagename, @pagetype, @pagebody, @ignoreError = dbid, pageid, pagename, pagetype, pagebody, ignoreError if pageid xmlRequestData = toXML( :pageid, @pageid ) elsif pagename xmlRequestData = toXML( :pagename, @pagename ) else raise "addReplaceDBPage: missing pageid or pagename" end xmlRequestData << toXML( :pagetype, @pagetype ) xmlRequestData << toXML( :pagebody, encodeXML( @pagebody ) ) xmlRequestData << toXML( :ignoreError, "1" ) if @ignoreError sendRequest( :addReplaceDBPage, xmlRequestData ) @pageid = getResponseValue( :pageid ) @pageid ||= getResponseValue( :pageID ) # temporary return self if @chainAPIcalls @pageid end
API_AddUserToGroup
# File lib/QuickBaseClient.rb, line 1738 def addUserToGroup( userid, groupid ) @userid, @groupid = userid, groupid xmlRequestData = toXML( :userid, @userid ) xmlRequestData << toXML( :groupid, @groupid ) sendRequest( :addUserToGroup, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
API_AddUserToRole
# File lib/QuickBaseClient.rb, line 1751 def addUserToRole( dbid, userid, roleid ) @dbid, @userid, @roleid = dbid, userid, roleid xmlRequestData = toXML( :userid, @userid ) xmlRequestData << toXML( :roleid, @roleid ) sendRequest( :addUserToRole, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
Add method aliases that follow the ruby method naming convention.
E.g. sendRequest will be aliased as send_request.
# File lib/QuickBaseClient.rb, line 5014 def alias_methods aliased_methods = [] public_methods.each{|old_method| if old_method.match(/[A-Z]+/) new_method = old_method.gsub(/[A-Z]+/){|uc| "_#{uc.downcase}"} aliased_methods << new_method instance_eval( "alias #{new_method} #{old_method}") end } aliased_methods end
Query records, get the average of the values in a numeric field, calculate each record’s deviation from the average and put the deviation in a percent field each record.
# File lib/QuickBaseClient.rb, line 4127 def applyDeviationToRecords( dbid, numericField, deviationField, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil) fieldNames = Array[numericField] avg = average( dbid, fieldNames, query, qid, qname, clist, slist, fmt, options ) fieldNames << "3" # Record ID# iterateRecords( dbid, fieldNames, query, qid, qname, clist, slist, fmt, options ){|record| result = deviation( [avg[numericField],record[numericField]] ) clearFieldValuePairList addFieldValuePair( deviationField, nil, nil, result.to_s ) editRecord( dbid, record["3"], fvlist ) } end
Query records, sum the values in a numeric field, calculate each record’s percentage of the sum and put the percent in a percent field each record.
# File lib/QuickBaseClient.rb, line 4112 def applyPercentToRecords( dbid, numericField, percentField, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil) fieldNames = Array[numericField] total = sum( dbid, fieldNames, query, qid, qname, clist, slist, fmt, options ) fieldNames << "3" # Record ID# iterateRecords( dbid, fieldNames, query, qid, qname, clist, slist, fmt, options ){|record| result = percent( [total[numericField],record[numericField]] ) clearFieldValuePairList addFieldValuePair( percentField, nil, nil, result.to_s ) editRecord( dbid, record["3"], fvlist ) } end
API_AssertFederatedIdentity (IPP only)
# File lib/QuickBaseClient.rb, line 1767 def assertFederatedIdentity( dbid, serviceProviderID, targetURL ) @dbid, @serviceProviderID, @targetURL = dbid, serviceProviderID, targetURL xmlRequestData = toXML( :serviceProviderID, @serviceProviderID ) xmlRequestData << toXML( :targetURL, @targetURL ) sendRequest( :assertFederatedIdentity, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
API_AttachIDSRealm (IPP only)
# File lib/QuickBaseClient.rb, line 1780 def attachIDSRealm( dbid, realm ) @dbid, @realm = dbid, realm xmlRequestData = toXML( :realm, @realm ) sendRequest( :attachIDSRealm, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
API_Authenticate
# File lib/QuickBaseClient.rb, line 1833 def authenticate( username, password, hours = nil ) @username, @password, @hours = username, password, hours if username and password @ticket = nil if @hours xmlRequestData = toXML( :hours, @hours ) sendRequest( :authenticate, xmlRequestData ) else sendRequest( :authenticate ) end @userid = getResponseValue( :userid ) return self if @chainAPIcalls return @ticket, @userid elsif username or password raise "authenticate: missing username or password" elsif @ticket raise "authenticate: #{username} is already authenticated" end end
Returns the average of the values for one or more fields in the records returned by a query. e.g. averagesHash = average(“dfdfafff”,[“Date Sent”,“Quantity”,“Part Name”])
# File lib/QuickBaseClient.rb, line 4074 def average( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) count = {} fieldNames.each{|field| count[field]=0 } sum = {} iterateRecords(dbid,fieldNames,query,qid,qname,clist,slist,fmt,options){|record| fieldNames.each{|field| value = record[field] if value baseFieldType = lookupBaseFieldTypeByName(field) case baseFieldType when "int32","int64","bool" value = record[field].to_i when "float" value = record[field].to_f end if sum[field].nil? sum[field] = value else sum[field] = sum[field] + value end count[field] += 1 end } } average = {} hasValues = false fieldNames.each{|field| if sum[field] and count[field] > 0 average[field] = (sum[field]/count[field]) hasValues = true end } average = nil if not hasValues average end
This method changes all the API_ wrapper methods to return ‘self’ instead of their normal return values. The change is in effect only within the associated block. This allows mutliple API_ calls to be ‘chained’ together without needing ‘qbClient’ in front of each call.
e.g. qbClient.chainAPIcallsBlock
{
qbClient .addField( @dbid, "a text field", "text" ) .addField( @dbid, "a choice field", "text" ) .fieldAddChoices( @dbid, @fid, %w{ one two three four five } ) }
# File lib/QuickBaseClient.rb, line 3189 def chainAPIcallsBlock if block_given? @chainAPIcalls = true yield end @chainAPIcalls = nil end
API_ChangePermission (appears to be deprecated)
# File lib/QuickBaseClient.rb, line 1859 def changePermission( dbid, uname, view, modify, create, delete, saveviews, admin ) raise "changePermission: API_ChangePermission is no longer a valid QuickBase HTTP API request." @dbid, @uname, @view, @modify, @create, @delete, @saveviews, @admin = dbid, uname, view, modify, create, delete, saveviews, admin xmlRequestData = toXML( :dbid, @dbid ) xmlRequestData << toXML( :uname, @uname ) viewModifyPermissions = %w{ none any own group } if @view if viewModifyPermissions.include?( @view ) xmlRequestData << toXML( :view, @view ) else raise "changePermission: view must be one of " + viewModifyPermissions.join( "," ) end end if @modify if viewModifyPermissions.include?( @modify ) xmlRequestData << toXML( :modify, @modify ) else raise "changePermission: modify must be one of " + viewModifyPermissions.join( "," ) end end xmlRequestData << toXML( :create, @create ) if @create xmlRequestData << toXML( :delete, @delete ) if @delete xmlRequestData << toXML( :saveviews, @saveviews ) if @saveviews xmlRequestData << toXML( :admin, @admin ) if @admin sendRequest( :changePermission, xmlRequestData ) # not sure the API reference is correct about these return values @username = getResponseValue( :username ) @view = getResponseValue( :view ) @modify = getResponseValue( :modify ) @create = getResponseValue( :create ) @delete = getResponseValue( :delete ) @saveviews = getResponseValue( :saveviews ) @admin = getResponseValue( :admin ) @rolename = getResponseValue( :rolename ) return self if @chainAPIcalls return @username, @view, @modify, @create, @delete, @saveviews, @admin, @rolename end
API_ChangeRecordOwner
# File lib/QuickBaseClient.rb, line 1912 def changeRecordOwner( dbid, rid, newowner ) @dbid, @rid, @newowner = dbid, rid, newowner xmlRequestData = toXML( :dbid, @dbid ) xmlRequestData << toXML( :rid, @rid ) xmlRequestData << toXML( :newowner, @newowner ) sendRequest( :changeRecordOwner, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
Change a field’s value in multiple records. If the optional test field/operator/value are supplied, only records matching the test field will be modified, otherwise all records will be modified. e.g. changeRecords( “Status”, “special”, “Account Balance”, “>”, “100000.00” )
# File lib/QuickBaseClient.rb, line 3242 def changeRecords( fieldNameToSet, fieldValueToSet, fieldNameToTest, test, fieldValueToTest ) if @dbid and @fields and fieldNameToSet and fieldValueToSet and fieldNameToTest and test and fieldValueToTest numRecsChanged = 0 numRecs = _getNumRecords if numRecs > "0" fieldType = "text" if fieldNameToTest fieldNameToTestID = lookupFieldIDByName( fieldNameToTest ) field = lookupField( fieldNameToTestID ) if fieldNameToTestID fieldType = field.attributes[ "field_type" ] if field end fieldNameToSetID = lookupFieldIDByName( fieldNameToSet ) if fieldNameToSetID clearFieldValuePairList addFieldValuePair( nil, fieldNameToSetID, nil, fieldValueToSet ) (1..numRecs.to_i).each{ |rid| _getRecordInfo( rid.to_s ) if @num_fields and @update_id and @field_data_list if fieldNameToTestID and test and fieldValueToTest field_data = lookupFieldData( fieldNameToTestID ) if field_data and field_data.is_a?( REXML::Element ) valueElement = field_data.elements[ "value" ] value = valueElement.text if valueElement.has_text? value = formatFieldValue( value, fieldType ) match = eval( "\"#{value}\" #{test} \"#{fieldValueToTest}\"" ) if value if match editRecord( @dbid, rid.to_s, @fvlist ) if @rid numRecsChanged += 1 end end end else editRecord( @dbid, rid.to_s, @fvlist ) if @rid numRecsChanged += 1 end end end } end end end numRecsChanged end
API_ChangeUserRole.
# File lib/QuickBaseClient.rb, line 1930 def changeUserRole( dbid, userid, roleid, newroleid ) @dbid, @userid, @roleid, @newroleid = dbid, userid, roleid, newroleid xmlRequestData = toXML( :userid, @userid ) xmlRequestData << toXML( :roleid, @roleid ) xmlRequestData << toXML( :newroleid, @newroleid ) sendRequest( :changeUserRole, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
Recursive method to generate a simplified (yaml-like) tree of the XML returned by QuickBase
.
Translates field IDs into field names.
# File lib/QuickBaseClient.rb, line 613 def childElementsAsString( element, indent = 0 ) ret = "" indentation = "" indent.times{ indentation << " " } if indent > 0 if element and element.is_a?( REXML::Element ) and element.has_elements? attributes = getAttributeString( element ) name = lookupFieldName( element ) ret << "#{indentation}#{name} #{attributes}:\r\n" element.each { |element| if element.is_a?( REXML::Element ) and element.has_elements? ret << childElementsAsString( element, (indent+1) ) elsif element.is_a?( REXML::Element ) and element.has_text? attributes = getAttributeString( element ) name = lookupFieldName( element ) text = formatFieldValue( element.text, lookupFieldType( element ) ) ret << " #{indentation}#{name} #{attributes} = #{text}\r\n" end } elsif element and element.is_a?( Array ) element.each{ |e| ret << childElementsAsString( e ) } end ret end
Empty the list of field values used for the next addRecord() or editRecord() call to QuickBase
.
# File lib/QuickBaseClient.rb, line 1187 def clearFieldValuePairList @fvlist = nil end
Return an array of all the public methods of this class. Used by CommandLineClient to verify commands entered by the user.
# File lib/QuickBaseClient.rb, line 199 def clientMethods Client.public_instance_methods( false ) end
API_CloneDatabase
# File lib/QuickBaseClient.rb, line 1947 def cloneDatabase( dbid, newdbname, newdbdesc, keepData, asTemplate = nil, usersAndRoles = nil ) @dbid, @newdbname, @newdbdesc, @keepData, @asTemplate, @usersAndRoles = dbid, newdbname, newdbdesc, keepData, asTemplate, usersAndRoles @keepData = "1" if @keepData.to_s == "true" @keepData = "0" if @keepData != "1" xmlRequestData = toXML( :newdbname, @newdbname ) xmlRequestData << toXML( :newdbdesc, @newdbdesc ) xmlRequestData << toXML( :keepData, @keepData ) xmlRequestData << toXML( :asTemplate, @asTemplate ) if @asTemplate xmlRequestData << toXML( :usersAndRoles, @usersAndRoles ) if @usersAndRoles sendRequest( :cloneDatabase, xmlRequestData ) @newdbid = getResponseValue( :newdbid ) return self if @chainAPIcalls @newdbid end
API_CopyMasterDetail
# File lib/QuickBaseClient.rb, line 1972 def copyMasterDetail( dbid, destrid, sourcerid, copyfid = nil, recurse = nil, relfids = nil ) raise "copyfid must be specified when destrid is 0." if destrid == "0" and copyfid.nil? @dbid, @destrid, @sourcerid, @copyfid, @recurse, @relfids = dbid, destrid, sourcerid, copyfid, recurse, relfids xmlRequestData = toXML( :destrid, @destrid) xmlRequestData << toXML( :sourcerid, @sourcerid ) xmlRequestData << toXML( :copyfid, @copyfid ) if @copyfid xmlRequestData << toXML( :recurse, @recurse ) if @recurse xmlRequestData << toXML( :relfids, @relfids ) if @relfids sendRequest( :copyMasterDetail, xmlRequestData ) @parentrid = getResponseValue( :parentrid ) @numCreated = getResponseValue( :numCreated ) return self if @chainAPIcalls return @parentrid, @numCreated end
Make one or more copies of a record.
# File lib/QuickBaseClient.rb, line 4284 def copyRecord( rid, numCopies = 1, dbid = @dbid ) clearFieldValuePairList getRecordInfo( dbid, rid ) { |field| if field and field.elements[ "value" ] and field.elements[ "value" ].has_text? if field.elements[ "fid" ].text.to_i > 5 #skip built-in fields addFieldValuePair( field.elements[ "name" ].text, nil, nil, field.elements[ "value" ].text ) end end } newRecordIDs = [] if @fvlist and @fvlist.length > 0 numCopies.times { addRecord( dbid, @fvlist ) newRecordIDs << @rid if @rid and @update_id } end if block_given? newRecordIDs.each{ |newRecordID| yield newRecordID } else newRecordIDs end end
Returns the number non-null values for one or more fields in the records returned by a query. e.g. countsHash = count(“dfdfafff”,[“Date Sent”,“Quantity”,“Part Name”])
# File lib/QuickBaseClient.rb, line 4027 def count( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) count = {} fieldNames.each{|field| count[field]=0 } hasValues = false iterateRecords(dbid,fieldNames,query,qid,qname,clist,slist,fmt,options){|record| fieldNames.each{|field| if record[field] and record[field].length > 0 count[field] += 1 hasValues = true end } } count = nil if not hasValues count end
API_CreateDatabase
# File lib/QuickBaseClient.rb, line 1997 def createDatabase( dbname, dbdesc, createapptoken = "1" ) @dbname, @dbdesc, @createapptoken = dbname, dbdesc, createapptoken xmlRequestData = toXML( :dbname, @dbname ) xmlRequestData << toXML( :dbdesc, @dbdesc ) xmlRequestData << toXML( :createapptoken, @createapptoken ) sendRequest( :createDatabase, xmlRequestData ) @dbid = getResponseValue( :dbid ) @appdbid = getResponseValue( :appdbid ) @apptoken = getResponseValue( :apptoken ) return self if @chainAPIcalls return @dbid, @appdbid end
API_CreateTable
# File lib/QuickBaseClient.rb, line 2016 def createTable( tname, pnoun, application_dbid = @dbid ) @tname, @pnoun, @dbid = tname, pnoun, application_dbid xmlRequestData = toXML( :tname, @tname ) xmlRequestData << toXML( :pnoun, @pnoun ) sendRequest( :createTable, xmlRequestData ) @newdbid = getResponseValue( :newdbid ) @newdbid ||= getResponseValue( :newDBID ) #temporary @dbid = @newdbid return self if @chainAPIcalls @newdbid end
Returns the milliseconds representation of a date specified in mm-dd-yyyy format.
# File lib/QuickBaseClient.rb, line 1489 def dateToMS( dateString ) milliseconds = 0 if dateString and dateString.match( /[0-9][0-9]\-[0-9][0-9]\-[0-9][0-9][0-9][0-9]/) d = Date.new( dateString[7,4], dateString[4,2], dateString[0,2] ) milliseconds = d.jd end milliseconds end
Causes useful information to be printed to the screen for every HTTP request.
# File lib/QuickBaseClient.rb, line 178 def debugHTTPConnection() @httpConnection.set_debug_output $stdout if @httpConnection and USING_HTTPCLIENT == false end
Modify the given XML field value for use as a string.
# File lib/QuickBaseClient.rb, line 1536 def decodeXML( text ) encodingStrings( true ) { |key,value| text.gsub!( value, key ) if text } text.gsub!( /&#([0-9]{2,3});/ ) { |c| $1.chr } if text text end
API_DeleteAppZip
# File lib/QuickBaseClient.rb, line 1804 def deleteAppZip( dbid ) @dbid = dbid sendRequest( :deleteAppZip ) return self if @chainAPIcalls @responseCode end
API_DeleteDatabase
# File lib/QuickBaseClient.rb, line 2032 def deleteDatabase( dbid ) @dbid = dbid sendRequest( :deleteDatabase ) @dbid = @rid = nil return self if @chainAPIcalls @requestSucceeded end
Finds records with the same values in a specified list of fields and deletes all but the first or last duplicate record. The field list may be a list of field IDs or a list of field names. The ‘options’ parameter can be used to keep the oldest record instead of the newest record, and to control whether to ignore the case of field values when deciding which records are duplicates. Returns the number of records deleted.
# File lib/QuickBaseClient.rb, line 4264 def deleteDuplicateRecords( fnames, fids = nil, options = nil, dbid = @dbid ) num_deleted = 0 if options and not options.is_a?( Hash ) raise "deleteDuplicateRecords: 'options' parameter must be a Hash" else options = {} options[ "keeplastrecord" ] = true options[ "ignoreCase" ] = true end findDuplicateRecordIDs( fnames, fids, dbid, options[ "ignoreCase" ] ) { |dupeValues, recordIDs| if options[ "keeplastrecord" ] recordIDs[0..(recordIDs.length-2)].each{ |rid| num_deleted += 1 if deleteRecord( dbid, rid ) } elsif options[ "keepfirstrecord" ] recordIDs[1..(recordIDs.length-1)].each{ |rid| num_deleted += 1 if deleteRecord( dbid, rid ) } end } num_deleted end
API_DeleteField
# File lib/QuickBaseClient.rb, line 2047 def deleteField( dbid, fid ) @dbid, @fid = dbid, fid xmlRequestData = toXML( :fid, @fid ) sendRequest( :deleteField, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
API_DeleteRecord
# File lib/QuickBaseClient.rb, line 2072 def deleteRecord( dbid, rid ) @dbid, @rid = dbid, rid xmlRequestData = toXML( :rid, @rid ) sendRequest( :deleteRecord, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
Delete all records in the active table that match the field/operator/value. e.g. deleteRecords( “Status”, “==”, “inactive” ). To delete ALL records, call deleteRecords() with no parameters. This is the same as calling _purgeRecords.
# File lib/QuickBaseClient.rb, line 3298 def deleteRecords( fieldNameToTest = nil, test = nil, fieldValueToTest = nil) numRecsDeleted = 0 if @dbid and @fields and fieldNameToTest and test and fieldValueToTest numRecs = _getNumRecords if numRecs > "0" fieldNameToTestID = lookupFieldIDByName( fieldNameToTest ) fieldToTest = lookupField( fieldNameToTestID ) if fieldNameToTestID fieldType = fieldToTest.attributes[ "field_type" ] if fieldToTest if fieldNameToTestID (1..numRecs.to_i).each{ |rid| _getRecordInfo( rid.to_s ) if @num_fields and @update_id and @field_data_list field_data = lookupFieldData( fieldNameToTestID ) if field_data and field_data.is_a?( REXML::Element ) valueElement = field_data.elements[ "value" ] value = valueElement.text if valueElement.has_text? value = formatFieldValue( value, fieldType ) match = eval( "\"#{value}\" #{test} \"#{fieldValueToTest}\"" ) if value if match if _deleteRecord( rid.to_s ) numRecsDeleted += 1 end end end end } end end elsif @dbid numRecsDeleted = _purgeRecords end numRecsDeleted end
API_DetachIDSRealm (IPP only)
# File lib/QuickBaseClient.rb, line 1792 def detachIDSRealm( dbid, realm ) @dbid, @realm = dbid, realm xmlRequestData = toXML( :realm, @realm ) sendRequest( :detachIDSRealm, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
Given an array of two numbers, return the difference between the numbers as a positive number.
# File lib/QuickBaseClient.rb, line 4152 def deviation( inputValues ) raise "'inputValues' must not be nil" if inputValues.nil? raise "'inputValues' must be an Array" if not inputValues.is_a?(Array) raise "'inputValues' must have at least two elements" if inputValues.length < 2 value = inputValues[0].to_f - inputValues[1].to_f value.abs end
API_DoQuery
# File lib/QuickBaseClient.rb, line 2086 def doQuery( dbid, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) @dbid, @clist, @slist, @fmt, @options = dbid, clist, slist, fmt, options @clist ||= getColumnListForQuery(qid, qname) @slist ||= getSortListForQuery(qid, qname) xmlRequestData = getQueryRequestXML( query, qid, qname ) xmlRequestData << toXML( :clist, @clist ) if @clist xmlRequestData << toXML( :slist, @slist ) if @slist xmlRequestData << toXML( :fmt, @fmt ) if @fmt xmlRequestData << toXML( :options, @options ) if @options sendRequest( :doQuery, xmlRequestData ) if @fmt and @fmt == "structured" @records = getResponseElement( "table/records" ) @fields = getResponseElement( "table/fields" ) @chdbids = getResponseElement( "table/chdbids" ) @queries = getResponseElement( "table/queries" ) @variables = getResponseElement( "table/variables" ) else @records = getResponseElements( "qdbapi/record" ) @fields = getResponseElements( "qdbapi/field" ) @chdbids = getResponseElements( "qdbapi/chdbid" ) @queries = getResponseElements( "qdbapi/query" ) @variables = getResponseElements( "qdbapi/variable" ) end return self if @chainAPIcalls if block_given? if @records @records.each { |element| yield element } else yield nil end else @records end end
API_DoQueryCount
# File lib/QuickBaseClient.rb, line 2152 def doQueryCount( dbid, query ) @dbid, @query = dbid, query xmlRequestData = toXML( :query, @query ) sendRequest( :doQueryCount, xmlRequestData ) @numMatches = getResponseValue( :numMatches ) return self if @chainAPIcalls @numMatches end
Translate a simple SQL INSERT statement to a QuickBase
addRecord call.
Note: This method is here primarily for Rails integration. Note: This assumes, like SQL, that your column (i.e. field) names do not contain spaces.
# File lib/QuickBaseClient.rb, line 4905 def doSQLInsert(sqlString) sql = sqlString.dup dbname = "" state = nil fieldName = "" fieldValue = "" fieldNames = [] fieldValues = [] index = 0 clearFieldValuePairList sql.gsub!("("," ") sql.gsub!(")"," ") sql.split(' ').each{ |token| case token when "INSERT", "INTO" state = "getTable" next when "VALUES" state = "getFieldValue" next end if state == "getTable" dbname = token.strip state = "getFieldName" elsif state == "getFieldName" fieldName = token.dup fieldName.gsub!("],","") fieldName.gsub!('[','') fieldName.gsub!(']','') fieldName.gsub!(',','') fieldNames << fieldName elsif state == "getFieldValue" test = token.dup if test[-1,1] == "'" or test[-2,2] == "'," fieldValue << token.dup if fieldValue[-2,2] == "'," fieldValue.gsub!("',",'') end fieldValue.gsub!('\'','') if fieldValue.length > 0 and fieldNames[index] addFieldValuePair(fieldNames[index],nil,nil,fieldValue) fieldName = "" fieldValue = "" end index += 1 elsif token == "," addFieldValuePair(fieldNames[index],nil,nil,"") fieldName = "" fieldValue = "" index += 1 else fieldValue << "#{token.dup} " end end } if dbname and @dbid.nil? dbid = findDBByname( dbname ) else dbid = lookupChdbid( dbname ) end dbid ||= @dbid recordid = nil if dbid recordid,updateid = addRecord(dbid,@fvlist) end recordid end
Translate a simple SQL SELECT statement to a QuickBase
query and run it.
If any supplied field names are numeric, they will be treated as QuickBase field IDs if they aren't valid field names.
-
e.g. doSQLQuery( “SELECT FirstName,Salary FROM Contacts WHERE LastName = ”Doe“ ORDER BY FirstName )
-
e.g. doSQLQuery( “SELECT * FROM Books WHERE Author = ”Freud“ )
Note: This method is here primarily for Rails integration. Note: This assumes, like SQL, that your column (i.e. field) names do not contain spaces.
# File lib/QuickBaseClient.rb, line 4654 def doSQLQuery( sqlString, returnOptions = nil ) ret = nil sql = sqlString.dup dbid = nil clist = nil slist = nil state = nil dbname = "" columns = [] sortFields = [] limit = nil offset = nil options = nil getRecordCount = false queryFields = [] query = "{'[" queryState = "getFieldName" queryField = "" sql.split(' ').each{ |token| case token when "SELECT" then state = "getColumns";next when "count(*)" then state = "getCount";next when "FROM" then state = "getTable";next when "WHERE" then state = "getFilter" ;next when "ORDER" then state = "getBy";next when "BY" then state = "getSort";next when "LIMIT" then state = "getLimit";next when "OFFSET" then state = "getOffset";next end if state == "getColumns" if token.index( "," ) token.split(",").each{ |column| columns << column if column.length > 0 } else columns << "#{token} " end elsif state == "getCount" getRecordCount = true elsif state == "getTable" dbname = token.strip elsif state == "getFilter" if token == "AND" query.strip! query << "'}AND{'[" queryState = "getFieldName" elsif token == "OR" query.strip! query << "'}OR{'[" queryState = "getFieldName" elsif token == "=" query << "]'.TV.'" queryState = "getFieldValue" queryFields << queryField queryField = "" elsif token == "<>" or token == "!=" query << "]'.XTV.'" queryState = "getFieldValue" queryFields << queryField queryField = "" elsif queryState == "getFieldValue" fieldValue = token.dup if fieldValue[-2,2] == "')" fieldValue[-1,1] = "" end if fieldValue[-1] == "'" fieldValue.gsub!("'","") query << "#{fieldValue}" else fieldValue.gsub!("'","") query << "#{fieldValue} " end elsif queryState == "getFieldName" fieldName = token.gsub("(","").gsub(")","").gsub( "#{dbname}.","") query << "#{fieldName}" queryField << "#{fieldName} " end elsif state == "getSort" if token.contains( "," ) token.split(",").each{ |sortField| sortFields << sortField if sortField.length > 0 } else sortFields << "#{token} " end elsif state == "getLimit" limit = token.dup if options.nil? options = "num-#{limit}" else options << ".num-#{limit}" end elsif state == "getOffset" offset = token.dup if options.nil? options = "skp-#{offset}" else options << ".skp-#{offset}" end end } if dbname and @dbid.nil? dbid = findDBByname( dbname ) else dbid = lookupChdbid( dbname ) end dbid ||= @dbid if dbid getDBInfo( dbid ) getSchema( dbid ) if columns.length > 0 if columns[0] == "* " columns = getFieldNames( dbid ) end columnNames = [] columns.each{ |column| column.strip! fid = lookupFieldIDByName( column ) if fid.nil? and column.match(/[0-9]+/) fid = column columnNames << lookupFieldNameFromID(fid) else columnNames << column end if fid if clist clist << ".#{fid}" else clist = fid end end } end if sortFields.length > 0 sortFields.each{ |sortField| sortField.strip! fid = lookupFieldIDByName( sortField ) if fid.nil? fid = sortField if sortField.match(/[0-9]+/) end if fid if slist slist << ".#{fid}" else slist = fid end end } end if queryFields.length > 0 query.strip! query << "'}" queryFields.each{ |fieldName| fieldName.strip! fid = lookupFieldIDByName( fieldName ) if fid query.gsub!( "'[#{fieldName} ]'", "'#{fid}'" ) end } else query = nil end if getRecordCount ret = getNumRecords(dbid) elsif returnOptions == :Hash ret = getAllValuesForFields(dbid, columnNames, query, nil, nil, clist, slist,"structured",options) elsif returnOptions == :Array ret = getAllValuesForFieldsAsArray(dbid, columnNames, query, nil, nil, clist, slist,"structured",options) else ret = doQuery( dbid, query, nil, nil, clist, slist, "structured", options ) end end ret end
Translate a simple SQL UPDATE statement to a QuickBase
editRecord call.
Note: This method is here primarily for Rails integration. Note: This assumes, like SQL, that your column (i.e. field) names do not contain spaces. Note: This assumes that Record ID# is the key field in your table.
# File lib/QuickBaseClient.rb, line 4835 def doSQLUpdate(sqlString) sql = sqlString.dup dbname = "" state = nil fieldName = "" fieldValue = "" sqlQuery = "SELECT 3 FROM " clearFieldValuePairList sql.split(' ').each{ |token| case token when "UPDATE" state = "getTable" unless state == "getFilter" next when "SET" state = "getFieldName" unless state == "getFilter" next when "=" sqlQuery << " = " if state == "getFilter" state = "getFieldValue" unless state == "getFilter" next when "WHERE" sqlQuery << " WHERE " state = "getFilter" next end if state == "getTable" dbname = token.dup sqlQuery << dbname elsif state == "getFieldName" fieldName = token.gsub('[','').gsub(']','') elsif state == "getFieldValue" test = token if test[-1,1] == "'" or test[-2,2] == "'," fieldValue << token if fieldValue[-2,2] == "'," state = "getFieldName" fieldValue.gsub!("',","") end fieldValue.gsub!("'","") if fieldName.length > 0 addFieldValuePair(fieldName,nil,nil,fieldValue) fieldName = "" fieldValue = "" end else fieldValue << "#{token} " end elsif state == "getFilter" sqlQuery << token end } rows = doSQLQuery(sqlQuery,:Array) if rows and @dbid and @fvlist idFieldName = lookupFieldNameFromID("3") rows.each{ |row| recordID = row[idFieldName] editRecord(@dbid,recordID,@fvlist) if recordID } end end
Download a file’s contents from a file attachment field in QuickBase
. You must write the contents to disk before a local file exists.
# File lib/QuickBaseClient.rb, line 2170 def downLoadFile( dbid, rid, fid, vid = "0" ) @dbid, @rid, @fid, @vid = dbid, rid, fid, vid @downLoadFileURL = "http://#{@org}.#{@domain}.com/up/#{dbid}/a/r#{rid}/e#{fid}/v#{vid}" if @useSSL @downLoadFileURL.gsub!( "http:", "https:" ) end @requestHeaders = { "Cookie" => "ticket=#{@ticket}" } if @printRequestsAndResponses puts puts "downLoadFile request: -------------------------------------" p @downLoadFileURL p @requestHeaders end begin if USING_HTTPCLIENT @responseCode = 404 @fileContents = @httpConnection.get_content( @downLoadFileURL, nil, @requestHeaders ) @responseCode = 200 if @fileContents else @responseCode, @fileContents = @httpConnection.get( @downLoadFileURL, @requestHeaders ) end rescue Net::HTTPBadResponse => @lastError rescue Net::HTTPHeaderSyntaxError => @lastError rescue StandardError => @lastError end if @printRequestsAndResponses puts puts "downLoadFile response: -------------------------------------" p @responseCode p @fileContents end return self if @chainAPIcalls return @responseCode, @fileContents end
Download and save a file from a file attachment field in QuickBase
. Use the filename parameter to override the file name from QuickBase
.
# File lib/QuickBaseClient.rb, line 2225 def downloadAndSaveFile( dbid, rid, fid, filename = nil, vid = "0" ) response, fileContents = downLoadFile( dbid, rid, fid, vid ) if fileContents and fileContents.length > 0 if filename and filename.length > 0 Misc.save_file( filename, fileContents ) else record = getRecord( rid, dbid, [fid] ) if record and record[fid] and record[fid].length > 0 Misc.save_file( record[fid], fileContents ) else Misc.save_file( "#{dbid}_#{rid}_#{fid}", fileContents ) end end end end
API_DumpAppZip
# File lib/QuickBaseClient.rb, line 1812 def dumpAppZip( dbid ) @dbid = dbid @noredirect = true xmlRequestData = toXML( :noredirect, "1" ) sendRequest( :dumpAppZip, xmlRequestData ) return self if @chainAPIcalls @responseCode end
Iterate record XML and yield only ‘f’ elements.
# File lib/QuickBaseClient.rb, line 4994 def eachField( record = @record ) if record and block_given? record.each{ |field| if field.is_a?( REXML::Element) and field.name == "f" and field.attributes["id"] @field = field yield field end } end nil end
Iterate @records XML and yield only ‘record’ elements.
# File lib/QuickBaseClient.rb, line 4981 def eachRecord( records = @records ) if records and block_given? records.each { |record| if record.is_a?( REXML::Element) and record.name == "record" @record = record yield record end } end nil end
API_EditRecord
# File lib/QuickBaseClient.rb, line 2242 def editRecord( dbid, rid, fvlist, disprec = nil, fform = nil, ignoreError = nil, update_id = nil, msInUTC =nil, key = nil ) @dbid, @rid, @fvlist, @disprec, @fform, @ignoreError, @update_id, @msInUTC, @key = dbid, rid, fvlist, disprec, fform, ignoreError, update_id, msInUTC, key setFieldValues( fvlist, false ) if fvlist.is_a?(Hash) xmlRequestData = toXML( :rid, @rid ) if @rid xmlRequestData = toXML( :key, @key ) if @key @fvlist.each{ |fv| xmlRequestData << fv } #see addFieldValuePair, clearFieldValuePairList, @fvlist xmlRequestData << toXML( :disprec, @disprec ) if @disprec xmlRequestData << toXML( :fform, @fform ) if @fform xmlRequestData << toXML( :ignoreError, "1" ) if @ignoreError xmlRequestData << toXML( :update_id, @update_id ) if @update_id xmlRequestData << toXML( :msInUTC, "1" ) if @msInUTC sendRequest( :editRecord, xmlRequestData ) @rid = getResponseValue( :rid ) @update_id = getResponseValue( :update_id ) return self if @chainAPIcalls return @rid, @update_id end
Set the values of fields in all records returned by a query. fieldValuesToSet must be a Hash of fieldnames+values, e.g. {“Location” => “Miami”, “Phone” => “343-4567”}
# File lib/QuickBaseClient.rb, line 3468 def editRecords(dbid,fieldValuesToSet,query=nil,qid=nil,qname=nil) edited_rids = [] if fieldValuesToSet and fieldValuesToSet.is_a?(Hash) verifyFieldList(fieldValuesToSet.keys,nil,dbid) recordIDs = getAllValuesForFields(dbid,["3"],query,qid,qname,"3") if recordIDs numRecords = recordIDs["3"].length (0..(numRecords-1)).each {|i| @rid = recordIDs["3"][i] setFieldValues(fieldValuesToSet) edited_rids << @rid } end else raise "'fieldValuesToSet' must be a Hash of field names and values." end edited_rids end
Modify the given string for use as a XML field value.
# File lib/QuickBaseClient.rb, line 1529 def encodeXML( text, doNPChars = false ) encodingStrings { |key,value| text.gsub!( key, value ) if text } text.gsub!( /([^;\/?:@&=+\$,A-Za-z0-9\-_.!~*'()# ])/ ) { |c| escapeXML( $1 ) } if text and doNPChars text end
Returns the list of string substitutions to make to encode or decode field values used in XML.
# File lib/QuickBaseClient.rb, line 1515 def encodingStrings( reverse = false ) @encodingStrings = [ {"&" => "&" }, {"<" => "<"} , {">" => ">"}, {"'" => "'"}, {"\"" => """ } ] if @encodingStrings.nil? if block_given? if reverse @encodingStrings.reverse_each{ |s| s.each{|k,v| yield v,k } } else @encodingStrings.each{ |s| s.each{|k,v| yield k,v } } end else @encodingStrings end end
Returns the URL-encoded version of a non-printing character.
# File lib/QuickBaseClient.rb, line 1505 def escapeXML( char ) if @xmlEscapes.nil? @xmlEscapes = {} (0..255).each{ |i| @xmlEscapes[ i.chr ] = sprintf( "&#%03d;", i ) } end return @xmlEscapes[ char ] if @xmlEscapes[ char ] char end
API_FieldAddChoices The choice parameter can be one choice string or an array of choice strings.
# File lib/QuickBaseClient.rb, line 2270 def fieldAddChoices( dbid, fid, choice ) @dbid, @fid, @choice = dbid, fid, choice xmlRequestData = toXML( :fid, @fid ) if @choice.is_a?( Array ) @choice.each { |c| xmlRequestData << toXML( :choice, c ) } elsif @choice.is_a?( String ) xmlRequestData << toXML( :choice, @choice ) end sendRequest( :fieldAddChoices, xmlRequestData ) @fid = getResponseValue( :fid ) @fname = getResponseValue( :fname ) @numadded = getResponseValue( :numadded ) return self if @chainAPIcalls return @fid, @name, @numadded end
API_FieldRemoveChoices The choice parameter can be one choice string or an array of choice strings.
# File lib/QuickBaseClient.rb, line 2307 def fieldRemoveChoices( dbid, fid, choice ) @dbid, @fid, @choice = dbid, fid, choice xmlRequestData = toXML( :fid, @fid ) if @choice.is_a?( Array ) @choice.each { |c| xmlRequestData << toXML( :choice, c ) } elsif @choice.is_a?( String ) xmlRequestData << toXML( :choice, @choice ) end sendRequest( :fieldRemoveChoices, xmlRequestData ) @fid = getResponseValue( :fid ) @fname = getResponseValue( :fname ) @numremoved = getResponseValue( :numremoved ) return self if @chainAPIcalls return @fid, @name, @numremoved end
Returns a field type string given the more human-friendly label for a field type.
# File lib/QuickBaseClient.rb, line 1054 def fieldTypeForLabel( fieldTypeLabel ) @fieldTypeLabelMap ||= Hash["Text","text","Numeric","float","Date / Time","timestamp","Date","date","Checkbox","checkbox","Database Link","dblink","Duration","duration","Email","email","File Attachment","file","Numeric-Currency","currency","Numeric-Rating","rating","Numeric-Percent","percent","Phone Number","phone","Relationship","fkey","Time Of Day","timeofday","URL","url","User","user","Record ID#","recordid","Report Link","dblink","iCalendar","icalendarbutton"] @fieldTypeLabelMap[fieldTypeLabel] end
API_FindDBByname
# File lib/QuickBaseClient.rb, line 2342 def findDBByname( dbname ) @dbname = dbname xmlRequestData = toXML( :dbname, @dbname ) sendRequest( :findDBByname, xmlRequestData ) @dbid = getResponseValue( :dbid ) return self if @chainAPIcalls @dbid end
Finds records with the same values in a specified list of fields.
The field list may be a list of field IDs or a list of field names. Returns a hash with the structure { “duplicated values” => [ rid, rid, … ] }
# File lib/QuickBaseClient.rb, line 4214 def findDuplicateRecordIDs( fnames, fids, dbid = @dbid, ignoreCase = true ) verifyFieldList( fnames, fids, dbid ) duplicates = {} if @fids cslist = @fids.join( "." ) ridFields = lookupFieldsByType( "recordid" ) if ridFields and ridFields.last cslist << "." recordidFid = ridFields.last.attributes["id"] cslist << recordidFid valuesUsed = {} doQuery( @dbid, nil, nil, nil, cslist ) { |record| next unless record.is_a?( REXML::Element) and record.name == "record" recordID = "" recordValues = [] record.each { |f| if f.is_a?( REXML::Element) and f.name == "f" and f.has_text? if recordidFid == f.attributes["id"] recordID = f.text else recordValues << f.text end end } if not valuesUsed[ recordValues ] valuesUsed[ recordValues ] = [] end valuesUsed[ recordValues ] << recordID } valuesUsed.each{ |valueArray, recordArray| if recordArray.length > 1 duplicates[ valueArray ] = recordArray end } end end if block_given? duplicates.each{ |duplicate| yield duplicate } else duplicates end end
Returns the first XML sub-element with the specified attribute value.
# File lib/QuickBaseClient.rb, line 709 def findElementByAttributeValue( elements, attribute_name, attribute_value ) element = nil if elements if elements.is_a?( REXML::Element ) elements.each_element_with_attribute( attribute_name, attribute_value ) { |e| element = e } elsif elements.is_a?( Array ) elements.each{ |e| if e.is_a?( REXML::Element ) and e.attributes[ attribute_name ] == attribute_value element = e end } end end element end
Returns an array of XML sub-elements with the specified attribute name.
# File lib/QuickBaseClient.rb, line 743 def findElementsByAttributeName( elements, attribute_name ) elementArray = [] if elements elements.each_element_with_attribute( attribute_name ) { |e| elementArray << e } end elementArray end
Returns an array of XML sub-elements with the specified attribute value.
# File lib/QuickBaseClient.rb, line 726 def findElementsByAttributeValue( elements, attribute_name, attribute_value ) elementArray = [] if elements if elements.is_a?( REXML::Element ) elements.each_element_with_attribute( attribute_name, attribute_value ) { |e| elementArray << e } elsif elements.is_a?( Array ) elements.each{ |e| if e.is_a?( REXML::Element ) and e.attributes[ attribute_name ] == attribute_value element = e end } end end elementArray end
Returns a string formatted for a currency value.
# File lib/QuickBaseClient.rb, line 1434 def formatCurrency( value, options = nil ) value ||= "0.00" if !value.include?( '.' ) value << ".00" end currencySymbol = currencyFormat = nil if options currencySymbol = options["currencySymbol"] currencyFormat = options["currencyFormat"] end if currencySymbol if currencyFormat if currencyFormat == "0" value = "#{currencySymbol}#{value}" elsif currencyFormat == "1" if value.include?("-") value.gsub!("-","-#{currencySymbol}") elsif value.include?("+") value.gsub!("+","+#{currencySymbol}") else value = "#{currencySymbol}#{value}" end elsif currencyFormat == "2" value = "#{value}#{currencySymbol}" end else value = "#{currencySymbol}#{value}" end end value end
Returns the human-readable string represntation of a date, given the milliseconds version of the date. Also needed for requests to QuickBase
.
# File lib/QuickBaseClient.rb, line 1387 def formatDate( milliseconds, fmtString = nil, addDay = false ) fmt = "" fmtString = "%m-%d-%Y" if fmtString.nil? if milliseconds milliseconds_s = milliseconds.to_s if milliseconds_s.length == 13 t = Time.at( milliseconds_s[0,10].to_i, milliseconds_s[10,3].to_i ) t += (60 * 60 * 24) if addDay fmt = t.strftime( fmtString ) elsif milliseconds_s.length > 0 t = Time.at( (milliseconds_s.to_i) / 1000 ) t += (60 * 60 * 24) if addDay fmt = t.strftime( fmtString ) end end fmt end
Converts milliseconds to hours and returns the value as a string.
# File lib/QuickBaseClient.rb, line 1406 def formatDuration( value, option = "hours" ) option = "hours" if option.nil? if value.nil? value = "" else seconds = (value.to_i/1000) minutes = (seconds/60) hours = (minutes/60) days = (hours/24) if option == "days" value = days.to_s elsif option == "hours" value = hours.to_s elsif option == "minutes" value = minutes.to_s end end value end
Returns a human-readable string representation of a QuickBase
field value.
Also required for subsequent requests to QuickBase
.
# File lib/QuickBaseClient.rb, line 560 def formatFieldValue( value, type, options = nil ) if value and type case type when "date" value = formatDate( value ) when "date / time","timestamp" value = formatDate( value, "%m-%d-%Y %I:%M %p" ) when "timeofday" value = formatTimeOfDay( value, options ) when "duration" value = formatDuration( value, options ) when "currency" value = formatCurrency( value, options ) when "percent" value = formatPercent( value, options ) end end value end
Returns the string required for emebedding CSV data in a request.
# File lib/QuickBaseClient.rb, line 1381 def formatImportCSV( csv ) "<![CDATA[#{csv}]]>" end
Returns a string formatted for a percent value, given the data from QuickBase
# File lib/QuickBaseClient.rb, line 1470 def formatPercent( value, options = nil ) if value percent = (value.to_f * 100) value = percent.to_s if value.include?(".") int,fraction = value.split('.') if fraction.to_i == 0 value = int else value = "#{int}.#{fraction[0,2]}" end end else value = "0" end value end
Returns a string format for a time of day value.
# File lib/QuickBaseClient.rb, line 1427 def formatTimeOfDay(milliseconds, format = "%I:%M %p" ) format ||= "%I:%M %p" timeOfDay = "" timeOfDay = Time.at(milliseconds.to_i/1000).utc.strftime(format) if milliseconds end
API_GenAddRecordForm
# File lib/QuickBaseClient.rb, line 2355 def genAddRecordForm( dbid, fvlist = nil ) @dbid, @fvlist = dbid, fvlist setFieldValues( fvlist, false ) if fvlist.is_a?(Hash) xmlRequestData = "" @fvlist.each { |fv| xmlRequestData << fv } if @fvlist #see addFieldValuePair, clearFieldValuePairList, @fvlist sendRequest( :genAddRecordForm, xmlRequestData ) @HTML = @responseXML return self if @chainAPIcalls @HTML end
API_GenResultsTable
# File lib/QuickBaseClient.rb, line 2375 def genResultsTable( dbid, query = nil, clist = nil, slist = nil, jht = nil, jsa = nil, options = nil, qid = nil, qname = nil ) @dbid, @query, @clist, @slist, @jht, @jsa, @options = dbid, query, clist, slist, jht, jsa, options @clist ||= getColumnListForQuery(qid, qname) @slist ||= getSortListForQuery(qid, qname) xmlRequestData = getQueryRequestXML( query, qid, qname ) xmlRequestData << toXML( :clist, @clist ) if @clist xmlRequestData << toXML( :slist, @slist ) if @slist xmlRequestData << toXML( :jht, @jht ) if @jht xmlRequestData << toXML( :jsa, @jsa ) if @jsa xmlRequestData << toXML( :options, @options ) if @options sendRequest( :genResultsTable, xmlRequestData ) @HTML = @responseXML return self if @chainAPIcalls @HTML end
Get an array of all the record IDs for a specified table. e.g. IDs = getAllRecordIDs( “dhnju5y7” ){ |id| puts “Record #{id}” }
# File lib/QuickBaseClient.rb, line 4188 def getAllRecordIDs( dbid ) rids = [] if dbid getSchema( dbid ) next_record_id = getResponseElement( "table/original/next_record_id" ) if next_record_id and next_record_id.has_text? next_record_id = next_record_id.text (1..next_record_id.to_i).each{ |rid| begin _getRecordInfo( rid ) rids << rid.to_s if update_id rescue end } end end if block_given? rids.each { |id| yield id } else rids end end
Get all the values for one or more fields from a specified table.
e.g. getAllValuesForFields( “dhnju5y7”, [ “Name”, “Phone” ] )
The results are returned in Hash, e.g. { “Name” => values[ “Name” ], “Phone” => values[ “Phone” ] } The parameters after ‘fieldNames’ are passed directly to the doQuery() API_ call.
Invalid 'fieldNames' will be treated as field IDs by default, e.g. getAllValuesForFields( "dhnju5y7", [ "3" ] ) returns a list of Record ID#s even if the 'Record ID#' field name has been changed.
# File lib/QuickBaseClient.rb, line 3346 def getAllValuesForFields( dbid, fieldNames = nil, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) if dbid getSchema(dbid) values = {} fieldIDs = {} if fieldNames and fieldNames.is_a?( String ) values[ fieldNames ] = [] fieldID = lookupFieldIDByName( fieldNames ) if fieldID fieldIDs[ fieldNames ] = fieldID elsif fieldNames.match(/[0-9]+/) # assume fieldNames is a field ID fieldIDs[ fieldNames ] = fieldNames end elsif fieldNames and fieldNames.is_a?( Array ) fieldNames.each{ |name| if name values[ name ] = [] fieldID = lookupFieldIDByName( name ) if fieldID fieldIDs[ fieldID ] = name elsif name.match(/[0-9]+/) # assume name is a field ID fieldIDs[ name ] = name end end } elsif fieldNames.nil? getFieldNames(dbid).each{|name| values[ name ] = [] fieldID = lookupFieldIDByName( name ) fieldIDs[ fieldID ] = name } end if clist clist << "." clist = fieldIDs.keys.join('.') elsif qid.nil? and qname.nil? clist = fieldIDs.keys.join('.') end if clist clist = clist.split('.') clist.uniq! clist = clist.join(".") end doQuery( dbid, query, qid, qname, clist, slist, fmt, options ) if @records and values.length > 0 and fieldIDs.length > 0 @records.each { |r| if r.is_a?( REXML::Element) and r.name == "record" values.each{ |k,v| v << "" } r.each{ |f| if f.is_a?( REXML::Element) and f.name == "f" fid = f.attributes[ "id" ] name = fieldIDs[ fid ] if fid if name and values[ name ] v = values[ name ] v[-1] = f.text if v and f.has_text? end end } end } end end if values and block_given? values.each{ |field, values| yield field, values } else values end end
Get all the values for one or more fields from a specified table. This also formats the field values instead of returning the raw value.
# File lib/QuickBaseClient.rb, line 3426 def getAllValuesForFieldsAsArray( dbid, fieldNames = nil, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) ret = [] valuesForFields = getAllValuesForFields(dbid, fieldNames, query, qid, qname, clist, slist,fmt,options) if valuesForFields fieldNames ||= getFieldNames(@dbid) if fieldNames and fieldNames[0] ret = Array.new(valuesForFields[fieldNames[0]].length) fieldType = {} fieldNames.each{|field|fieldType[field]=lookupFieldTypeByName(field)} valuesForFields.each{ |field,values| values.each_index { |i| ret[i] ||= {} ret[i][field]=formatFieldValue(values[i],fieldType[field]) } } end end ret end
Get all the values for one or more fields from a specified table, in JSON format. This formats the field values instead of returning raw values.
# File lib/QuickBaseClient.rb, line 3450 def getAllValuesForFieldsAsJSON( dbid, fieldNames = nil, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) ret = getAllValuesForFieldsAsArray(dbid,fieldNames,query,qid,qname,clist,slist,fmt,options) ret = JSON.generate(ret) if ret end
Get all the values for one or more fields from a specified table, in human-readable JSON format. This formats the field values instead of returning raw values.
# File lib/QuickBaseClient.rb, line 3459 def getAllValuesForFieldsAsPrettyJSON( dbid, fieldNames = nil, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) ret = getAllValuesForFieldsAsArray(dbid,fieldNames,query,qid,qname,clist,slist,fmt,options) ret = JSON.pretty_generate(ret) if ret end
API_GetAncestorInfo
# File lib/QuickBaseClient.rb, line 2401 def getAncestorInfo( dbid ) @dbid = dbid sendRequest( :getAncestorInfo ) @ancestorappid = getResponseValue( :ancestorappid ) @oldestancestorappid = getResponseValue( :oldestancestorappid ) @qarancestorappid = getResponseValue( :qarancestorappid ) return self if @chainAPIcalls return @ancestorappid, @oldestancestorappid, @qarancestorappid end
API_GetAppDTMInfo
# File lib/QuickBaseClient.rb, line 2417 def getAppDTMInfo( dbid ) @dbid = dbid sendRequest( :getAppDTMInfo ) @requestTime = getResponseElement( "RequestTime" ) @requestNextAllowedTime = getResponseElement( "RequestNextAllowedTime" ) @app = getResponseElement( "app" ) @lastModifiedTime = getResponsePathValue( "app/lastModifiedTime" ) @lastRecModTime = getResponsePathValue( "app/lastRecModTime" ) @tables = getResponseElement( :tables ) return self if @chainAPIcalls if @app and @tables and block_given? @app.each { |element| yield element } @tables.each { |element| yield element } else return @app, @tables end end
Get the value of an application variable.
# File lib/QuickBaseClient.rb, line 867 def getApplicationVariable(variableName,dbid=nil) variablesHash = getApplicationVariables(dbid) variablesHash[variableName] end
Get a Hash of application variables.
# File lib/QuickBaseClient.rb, line 852 def getApplicationVariables(dbid=nil) variablesHash = {} dbid ||= @dbid getSchema(dbid) if @variables @variables.each_element_with_attribute( "name" ){ |var| if var.name == "var" and var.has_text? variablesHash[var.attributes["name"]] = var.text end } end variablesHash end
Returns a string representation of the attributes of an XML element.
# File lib/QuickBaseClient.rb, line 465 def getAttributeString( element ) attributes = "" if element.is_a?( REXML::Element ) and element.has_attributes? attributes = "(" element.attributes.each { |name,value| attributes << "#{name}=#{value} " } attributes << ")" end attributes end
Returns the request XML for either a ticket or a username and password. The XML includes a apptoken if one has been set.
# File lib/QuickBaseClient.rb, line 304 def getAuthenticationXMLforRequest( api_Request ) @authenticationXML = "" if @ticket @authenticationXML = toXML( :ticket, @ticket ) elsif @username and @password @authenticationXML = toXML( :username, @username ) + toXML( :password, @password ) end @authenticationXML << toXML( :apptoken, @apptoken ) if @apptoken end
API_GetBillingStatus
# File lib/QuickBaseClient.rb, line 2443 def getBillingStatus( dbid ) @dbid = dbid sendRequest( :getBillingStatus ) @lastPaymentDate = getResponseValue( :lastPaymentDate ) @status = getResponseValue( :status ) return self if @chainAPIcalls return @lastPaymentDate, @status end
Get the CSV data for a Report.
# File lib/QuickBaseClient.rb, line 4560 def getCSVForReport(dbid,query=nil,qid=nil,qname=nil) genResultsTable(dbid,query,nil,nil,nil,nil,"csv",qid,qname) end
Returns the clist associated with a query.
# File lib/QuickBaseClient.rb, line 1254 def getColumnListForQuery( id, name ) clistForQuery = nil if id query = lookupQuery( id ) elsif name query = lookupQueryByName( name ) end if query and query.elements["qyclst"] clistForQuery = query.elements["qyclst"].text.dup end clistForQuery end
Returns the criteria associated with a query.
# File lib/QuickBaseClient.rb, line 1286 def getCriteriaForQuery( id, name ) criteriaForQuery = nil if id query = lookupQuery( id ) elsif name query = lookupQueryByName( name ) end if query and query.elements["qycrit"] criteriaForQuery = query.elements["qycrit"].text.dup end criteriaForQuery end
API_GetDBInfo
# File lib/QuickBaseClient.rb, line 2459 def getDBInfo( dbid ) @dbid = dbid sendRequest( :getDBInfo ) @lastRecModTime = getResponseValue( :lastRecModTime ) @lastModifiedTime = getResponseValue( :lastModifiedTime ) @createdTime = getResponseValue( :createdTime ) @lastAccessTime = getResponseValue( :lastAccessTime ) @numRecords = getResponseValue( :numRecords ) @mgrID = getResponseValue( :mgrID ) @mgrName = getResponseValue( :mgrName ) @dbname = getResponseValue( :dbname) @version = getResponseValue( :version) return self if @chainAPIcalls return @lastRecModTime, @lastModifiedTime, @createdTime, @lastAccessTime, @numRecords, @mgrID, @mgrName end
API_GetDBPage
# File lib/QuickBaseClient.rb, line 2482 def getDBPage( dbid, pageid, pagename = nil ) @dbid, @pageid, @pagename = dbid, pageid, pagename xmlRequestData = nil if @pageid xmlRequestData = toXML( :pageid, @pageid ) elsif @pagename xmlRequestData = toXML( :pagename, @pagename ) else raise "getDBPage: missing pageid or pagename" end sendRequest( :getDBPage, xmlRequestData ) @pagebody = getResponseElement( :pagebody ) return self if @chainAPIcalls @pagebody end
Get an array Pages for an application. Each item in the array is a Hash.
# File lib/QuickBaseClient.rb, line 3148 def getDBPagesAsArray(dbid) dbPagesArray = [] iterateDBPages(dbid){|page| dbPagesArray << page } dbPagesArray end
Determines whether the URL for a QuickBase
request is for a specific database table or not, and returns the appropriate string for that portion of the request URL.
# File lib/QuickBaseClient.rb, line 292 def getDBforRequestURL( api_Request ) @dbidForRequestURL = "/db/#{@dbid}" case api_Request when :getAppDTMInfo @dbidForRequestURL = "/db/main?a=#{:getAppDTMInfo}&dbid=#{@dbid}" when :authenticate, :createDatabase, :deleteAppZip, :dumpAppZip, :getUserInfo, :findDBByname, :getOneTimeTicket, :getFileUploadToken, :grantedDBs, :installAppZip, :obStatus, :signOut @dbidForRequestURL = "/db/main" end end
API_GetDBVar
# File lib/QuickBaseClient.rb, line 2507 def getDBvar( dbid, varname ) @dbid, @varname = dbid, varname xmlRequestData = toXML( :varname, @varname ) sendRequest( :getDBvar, xmlRequestData ) @value = getResponseValue( :value ) return self if @chainAPIcalls @value end
API_GetEntitlementValues
# File lib/QuickBaseClient.rb, line 2524 def getEntitlementValues( dbid ) @dbid = dbid sendRequest( :getEntitlementValues ) @productID = getResponseValue( :productID ) @planName = getResponseValue( :planName ) @planType = getResponseValue( :planType ) @maxUsers = getResponseValue( :maxUsers ) @currentUsers = getResponseValue( :currentUsers ) @daysRemainingTrial = getResponseValue( :daysRemainingTrial ) @entitlements = getResponseElement( :entitlements ) return self if @chainAPIcalls return @productID, @planName, @planType, @maxUsers, @currentUsers, @daysRemainingTrial, @entitlements end
Extracts error info from XML responses returned by QuickBase
.
# File lib/QuickBaseClient.rb, line 392 def getErrorInfoFromResponse if @responseXMLdoc errcode = getResponseValue( :errcode ) @errcode = errcode ? errcode : "" errtext = getResponseValue( :errtext ) @errtext = errtext ? errtext : "" errdetail = getResponseValue( :errdetail ) @errdetail = errdetail ? errdetail : "" if @errcode != "0" @lastError = "Error code: #{@errcode} text: #{@errtext}: detail: #{@errdetail}" end end @lastError end
Get an array of the existing choices for a multiple-choice text field.
# File lib/QuickBaseClient.rb, line 4161 def getFieldChoices(dbid,fieldName=nil,fid=nil) getSchema(dbid) if fieldName fid = lookupFieldIDByName(fieldName) elsif not fid raise "'fieldName' or 'fid' must be specified" end field = lookupField( fid ) if field choices = [] choicesProc = proc { |element| if element.is_a?(REXML::Element) if element.name == "choice" and element.has_text? choices << element.text end end } processChildElements(field,true,choicesProc) choices = nil if choices.length == 0 choices else nil end end
Returns the printable value for a field returned by a getRecordInfo call.
# File lib/QuickBaseClient.rb, line 787 def getFieldDataPrintableValue(fid) printable = nil if @field_data_list field_data = lookupFieldData(fid) if field_data printableElement = field_data.elements[ "printable" ] printable = printableElement.text if printableElement and printableElement.has_text? end end printable end
Returns the value for a field returned by a getRecordInfo call.
# File lib/QuickBaseClient.rb, line 774 def getFieldDataValue(fid) value = nil if @field_data_list field_data = lookupFieldData(fid) if field_data valueElement = field_data.elements[ "value" ] value = valueElement.text if valueElement.has_text? end end value end
Get an array of field IDs for a table.
# File lib/QuickBaseClient.rb, line 816 def getFieldIDs(dbid = nil, exclude_built_in_fields = false ) fieldIDs = [] dbid ||= @dbid getSchema(dbid) if @fields @fields.each_element_with_attribute( "id" ){|f| next if exclude_built_in_fields and isBuiltInField?(f.attributes["id"]) fieldIDs << f.attributes[ "id" ].dup } end fieldIDs end
Get an array of field names for a table.
# File lib/QuickBaseClient.rb, line 830 def getFieldNames( dbid = nil, lowerOrUppercase = "", exclude_built_in_fields = false ) fieldNames = [] dbid ||= @dbid getSchema(dbid) if @fields @fields.each_element_with_attribute( "id" ){ |f| next if exclude_built_in_fields and isBuiltInField?(f.attributes["id"]) if f.name == "field" if lowerOrUppercase == "lowercase" fieldNames << f.elements[ "label" ].text.downcase elsif lowerOrUppercase == "uppercase" fieldNames << f.elements[ "label" ].text.upcase else fieldNames << f.elements[ "label" ].text.dup end end } end fieldNames end
API_GetFileAttachmentUsage
# File lib/QuickBaseClient.rb, line 2545 def getFileAttachmentUsage( dbid ) @dbid = dbid sendRequest( :getFileAttachmentUsage ) @accountLimit = getResponseValue( :accountLimit ) @accountUsage = getResponseValue( :accountUsage ) @applicationLimit = getResponseValue( :applicationLimit ) @applicationUsage = getResponseValue( :applicationUsage ) return self if @chainAPIcalls return @accountLimit, @accountUsage, @applicationLimit, @applicationUsage end
Get the URL string for downloading a file from a File Attachment field
# File lib/QuickBaseClient.rb, line 4605 def getFileDownloadURL(dbid, rid, fid, vid = "0",org="www",domain="quickbase",ssl="s") "http#{ssl}://#{org}.#{domain}.com/up/#{dbid}/a/r#{rid}/e#{fid}/v#{vid}" end
API_GetFileUploadToken
# File lib/QuickBaseClient.rb, line 2589 def getFileUploadToken() sendRequest( :getFileUploadToken) @fileUploadToken = getResponseValue( :fileUploadToken ) @userid = getResponseValue( :userid ) return self if @chainAPIcalls return @fileUploadToken, @userid end
e.g. getFilteredRecords( “dhnju5y7”, [{“Name” => “[A-E].+”},“Address”] ) { |values| puts values, values }
# File lib/QuickBaseClient.rb, line 3541 def getFilteredRecords( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) filteredRecords = [] iterateFilteredRecords(dbid, fieldNames, query, qid, qname, clist, slist, fmt, options){ |filteredRecord| filteredRecords << filteredRecord } filteredRecords end
API_GetIDSRealm (IPP only)
# File lib/QuickBaseClient.rb, line 1822 def getIDSRealm( dbid ) @dbid = dbid sendRequest( :getIDSRealm ) @realm = getResponseValue( :realm) return self if @chainAPIcalls @realm end
Get an array of records from two or more tables and/or queries with the same value in a ‘join’ field. The ‘joinfield’ does not have to have the same name in each table. Fields with the same name in each table will be merged, with the value from the last table being assigned. This is similar to an SQL JOIN.
# File lib/QuickBaseClient.rb, line 3666 def getJoinRecords(tablesAndFields) joinRecords = [] iterateJoinRecords(tablesAndFields) { |joinRecord| joinRecords << joinRecord.dup } joinRecords end
API_GetNumRecords
# File lib/QuickBaseClient.rb, line 2563 def getNumRecords( dbid ) @dbid = dbid sendRequest( :getNumRecords ) @num_records = getResponseValue( :num_records ) return self if @chainAPIcalls @num_records end
Get the number of child tables of an application
# File lib/QuickBaseClient.rb, line 987 def getNumTables(dbid) numTables = 0 dbid ||= @dbid if getSchema(dbid) if @chdbids chdbidArray = findElementsByAttributeName( @chdbids, "name" ) numTables = chdbidArray.length end end numTables end
API_GetOneTimeTicket
# File lib/QuickBaseClient.rb, line 2577 def getOneTimeTicket() sendRequest( :getOneTimeTicket ) @ticket = getResponseValue( :ticket ) @userid = getResponseValue( :userid ) return self if @chainAPIcalls return @ticket, @userid end
Builds the request XML for retrieving the results of a query.
# File lib/QuickBaseClient.rb, line 1235 def getQueryRequestXML( query = nil, qid = nil, qname = nil ) @query = @qid = @qname = nil if query @query = query == "" ? "{'0'.CT.''}" : query xmlRequestData = toXML( :query, @query ) elsif qid @qid = qid xmlRequestData = toXML( :qid, @qid ) elsif qname @qname = qname xmlRequestData = toXML( :qname, @qname ) else @query = "{'0'.CT.''}" xmlRequestData = toXML( :query, @query ) end xmlRequestData end
Given a DBID, get the QuickBase
realm it is in.
# File lib/QuickBaseClient.rb, line 1017 def getRealmForDbid(dbid) @realm = nil if USING_HTTPCLIENT begin httpclient = HTTPClient.new resp = httpclient.get("https://www.quickbase.com/db/#{dbid}") location = resp.header['Location'][0] location.sub!("https://","") parts = location.split(/\./) @realm = parts[0] rescue StandardError => error @realm = nil end else raise "Please get the HTTPClient gem: gem install httpclient" end @realm end
Get a record as a Hash, using the record id and dbid . e.g. getRecord(“24105”,“8emtadvk”){|myRecord| p myRecord}
# File lib/QuickBaseClient.rb, line 3105 def getRecord(rid, dbid = @dbid, fieldNames = nil) rec = nil fieldNames ||= getFieldNames(dbid) iterateRecords(dbid, fieldNames,"{'3'.EX.'#{rid}'}"){|r| rec = r } if block_given? yield rec else rec end end
API_GetRecordAsHTML
# File lib/QuickBaseClient.rb, line 2601 def getRecordAsHTML( dbid, rid, jht = nil, dfid = nil ) @dbid, @rid, @jht, @dfid = dbid, rid, jht, dfid xmlRequestData = toXML( :rid, @rid ) xmlRequestData << toXML( :jht, "1" ) if @jht xmlRequestData << toXML( :dfid, @dfid ) if @dfid sendRequest( :getRecordAsHTML, xmlRequestData ) @HTML = @responseXML return self if @chainAPIcalls @HTML end
API_GetRecordInfo
# File lib/QuickBaseClient.rb, line 2621 def getRecordInfo( dbid, rid ) @dbid, @rid = dbid, rid xmlRequestData = toXML( :rid , @rid ) sendRequest( :getRecordInfo, xmlRequestData ) @num_fields = getResponseValue( :num_fields ) @update_id = getResponseValue( :update_id ) @rid = getResponseValue( :rid ) @field_data_list = getResponseElements( "qdbapi/field" ) return self if @chainAPIcalls if block_given? @field_data_list.each { |field| yield field } else return @num_fields, @update_id, @field_data_list end end
Get an array of records as Hashes, using the record ids and dbid . e.g. getRecords(,“8emtadvk”){|myRecord| p myRecord}
# File lib/QuickBaseClient.rb, line 3118 def getRecords(rids, dbid = @dbid, fieldNames = nil) records = [] if rids.length > 0 query = "" rids.each{|rid| query << "{'3'.EX.'#{rid}'}OR"} query[-2] = "" fieldNames ||= getFieldNames(dbid) iterateRecords(dbid,fieldNames,query){|r| records << r } end if block_given? records.each{|rec|yield rec} else records end end
Get a list of the names of the reports (i.e. queries) for a table.
# File lib/QuickBaseClient.rb, line 1000 def getReportNames(dbid = @dbid) reportNames = [] getSchema(dbid) if @queries queriesProc = proc { |element| if element.is_a?(REXML::Element) if element.name == "qyname" and element.has_text? reportNames << element.text end end } processChildElements(@queries,true,queriesProc) end reportNames end
Gets the element at an Xpath in the XML from QuickBase
.
# File lib/QuickBaseClient.rb, line 457 def getResponseElement( path ) if path and @responseXMLdoc @responseElement = @responseXMLdoc.root.elements[ path.to_s ] end @responseElement end
Gets an array of elements at an Xpath in the XML from QuickBase
.
# File lib/QuickBaseClient.rb, line 449 def getResponseElements( path ) if path and @responseXMLdoc @responseElements = @responseXMLdoc.get_elements( path.to_s ) end @responseElements end
Gets the value of a field using an XPath spec., e.g. field/name
# File lib/QuickBaseClient.rb, line 431 def getResponsePathValue( path ) @fieldValue = "" e = getResponseElement( path ) if e and e.is_a?( REXML::Element ) and e.has_text? @fieldValue = e.text end @fieldValue end
Gets an array of values at an Xpath in the XML from QuickBase
.
# File lib/QuickBaseClient.rb, line 441 def getResponsePathValues( path ) @fieldValue = "" e = getResponseElements( path ) e.each{ |e| @fieldValue << e.text if e and e.is_a?( REXML::Element ) and e.has_text? } @fieldValue end
Gets the value for a specific field at the top level of the XML returned from QuickBase
.
# File lib/QuickBaseClient.rb, line 421 def getResponseValue( field ) @fieldValue = nil if field and @responseXMLdoc @fieldValue = @responseXMLdoc.root.elements[ field.to_s ] @fieldValue = fieldValue.text if fieldValue and fieldValue.has_text? end @fieldValue end
API_GetRoleInfo
# File lib/QuickBaseClient.rb, line 2647 def getRoleInfo( dbid ) @dbid = dbid sendRequest( :getRoleInfo ) @roles = getResponseElement( :roles ) return self if @chainAPIcalls if block_given? role_list = getResponseElements( "qdbapi/roles/role" ) if role_list role_list.each {|role| yield role} else yield nil end else @roles end end
API_GetSchema
# File lib/QuickBaseClient.rb, line 2673 def getSchema( dbid ) @dbid = dbid if @cacheSchemas and @cachedSchemas and @cachedSchemas[dbid] @responseXMLdoc = @cachedSchemas[dbid] else sendRequest( :getSchema ) if @cacheSchemas and @requestSucceeded @cachedSchemas ||= {} @cachedSchemas[dbid] ||= @responseXMLdoc.dup end end @chdbids = getResponseElement( "table/chdbids" ) @variables = getResponseElement( "table/variables" ) @fields = getResponseElement( "table/fields" ) @queries = getResponseElement( "table/queries" ) @table = getResponseElement( :table ) @key_fid = getResponseElement( "table/original/key_fid" ) @key_fid = @key_fid.text if @key_fid and @key_fid.has_text? return self if @chainAPIcalls if @table and block_given? @table.each { |element| yield element } else @table end end
Get the status of the QuickBase
server.
# File lib/QuickBaseClient.rb, line 2726 def getServerStatus obStatus end
Returns the slist associated with a query.
# File lib/QuickBaseClient.rb, line 1270 def getSortListForQuery( id, name ) slistForQuery = nil if id query = lookupQuery( id ) elsif name query = lookupQueryByName( name ) end if query and query.elements["qyslst"] slistForQuery = query.elements["qyslst"].text.dup end slistForQuery end
Collect summary records into an array.
# File lib/QuickBaseClient.rb, line 3843 def getSummaryRecords( dbid, fieldNames,query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) summaryRecords = [] iterateSummaryRecords(dbid, fieldNames,query, qid, qname, clist, slist, fmt = "structured", options){|summaryRecord| summaryRecords << summaryRecord.dup } summaryRecords end
Get a list of the dbids of the child tables of an application.
# File lib/QuickBaseClient.rb, line 971 def getTableIDs(dbid) tableIDs = [] dbid ||= @dbid getSchema(dbid) if @chdbids chdbidArray = findElementsByAttributeName( @chdbids, "name" ) chdbidArray.each{ |chdbid| if chdbid.has_text? tableIDs << chdbid.text end } end tableIDs end
Get the name of a table given its id.
# File lib/QuickBaseClient.rb, line 934 def getTableName(dbid) tableName = nil dbid ||= @dbid if getSchema(dbid) tableName = getResponseElement( "table/name" ).text end tableName end
Get a list of the names of the child tables of an application.
# File lib/QuickBaseClient.rb, line 944 def getTableNames(dbid, lowercaseOrUpperCase = "") tableNames = [] dbid ||= @dbid getSchema(dbid) if @chdbids chdbidArray = findElementsByAttributeName( @chdbids, "name" ) chdbidArray.each{ |chdbid| if chdbid.has_text? dbid = chdbid.text getSchema( dbid ) name = getResponseElement( "table/name" ) if name and name.has_text? if lowercaseOrUpperCase == "lowercase" tableNames << name.text.downcase elsif lowercaseOrUpperCase == "uppercase" tableNames << name.text.upcase else tableNames << name.text.dup end end end } end tableNames end
Returns an Array of values from the same fields in two or more tables and/or queries. The merged records will be unique. This is similar to an SQL UNION.
# File lib/QuickBaseClient.rb, line 3725 def getUnionRecords(tables,fieldNames) unionRecords = [] iterateUnionRecords(tables,fieldNames) { |unionRecord| unionRecords << unionRecord.dup } unionRecords end
API_GetUserInfo
# File lib/QuickBaseClient.rb, line 2731 def getUserInfo( email = nil ) @email = email if @email and @email.length > 0 xmlRequestData = toXML( :email, @email) sendRequest( :getUserInfo, xmlRequestData ) else sendRequest( :getUserInfo ) @login = getResponsePathValue( "user/login" ) end @name = getResponsePathValue( "user/name" ) @firstName = getResponsePathValue( "user/firstName" ) @lastName = getResponsePathValue( "user/lastName" ) @login = getResponsePathValue( "user/login" ) @email = getResponsePathValue( "user/email" ) @screenName = getResponsePathValue( "user/screenName" ) @externalAuth = getResponsePathValue( "user/externalAuth" ) @user = getResponseElement( :user ) @userid = @user.attributes["id"] if @user return self if @chainAPIcalls @user end
API_GetUserRole
# File lib/QuickBaseClient.rb, line 2757 def getUserRole( dbid, userid, inclgrps = nil ) @dbid, @userid, @inclgrps = dbid, userid, inclgrps xmlRequestData = toXML( :userid , @userid ) xmlRequestData << toXML( :inclgrps , "1" ) if @inclgrps sendRequest( :getUserRole, xmlRequestData ) @user = getResponseElement( :user ) @userid = @user.attributes["id"] if @user @username = getResponsePathValue("user/name") @role = getResponseElement( "user/roles/role" ) @roleid = @role.attributes["id"] if @role @rolename = getResponsePathValue("user/roles/role/name") access = getResponseElement("user/roles/role/access") @accessid = access.attributes["id"] if access @access = getResponsePathValue("user/roles/role/access") if access member = getResponseElement("user/roles/role/member") @member_type = member.attributes["type"] if member @member = getResponsePathValue("user/roles/role/member") if member return self if @chainAPIcalls return @user, @role end
API_GrantedDBs
# File lib/QuickBaseClient.rb, line 2785 def grantedDBs( withembeddedtables = nil, excludeparents = nil, adminOnly = nil, includeancestors = nil, showAppData = nil ) @withembeddedtables, @excludeparents, @adminOnly, @includeancestors, @showAppData = withembeddedtables, excludeparents, adminOnly, includeancestors, showAppData xmlRequestData = "" xmlRequestData << toXML( :withembeddedtables, @withembeddedtables ) if @withembeddedtables xmlRequestData << toXML( "Excludeparents", @excludeparents ) if @excludeparents xmlRequestData << toXML( :adminOnly, @adminOnly ) if @adminOnly xmlRequestData << toXML( :includeancestors, @includeancestors ) if @includeancestors xmlRequestData << toXML( :showAppData, @showAppData ) if @showAppData sendRequest( :grantedDBs, xmlRequestData ) @databases = getResponseElement( :databases ) return self if @chainAPIcalls if @databases and block_given? @databases.each { |element| yield element } else @databases end end
Add records from lines in a CSV file. If dbid is not specified, the active table will be used. values in subsequent lines. The file must not contain commas inside field names or values.
# File lib/QuickBaseClient.rb, line 4394 def importCSVFile( filename, dbid = @dbid, targetFieldNames = nil, validateLines = true ) importSVFile( filename, ",", dbid, targetFieldNames, validateLines ) end
API_ImportFromCSV
# File lib/QuickBaseClient.rb, line 2810 def importFromCSV( dbid, records_csv, clist, skipfirst = nil, msInUTC = nil ) @dbid, @records_csv, @clist, @skipfirst, @msInUTC = dbid, records_csv, clist, skipfirst, msInUTC @clist ||= "0" xmlRequestData = toXML( :records_csv, @records_csv ) xmlRequestData << toXML( :clist, @clist ) xmlRequestData << toXML( :skipfirst, "1" ) if @skipfirst xmlRequestData << toXML( :msInUTC, "1" ) if @msInUTC sendRequest( :importFromCSV, xmlRequestData ) @num_recs_added = getResponseValue( :num_recs_added ) @num_recs_input = getResponseValue( :num_recs_input ) @num_recs_updated = getResponseValue( :num_recs_updated ) @rids = getResponseElement( :rids ) @update_id = getResponseValue( :update_id ) return self if @chainAPIcalls if block_given? @rids.each{ |rid| yield rid } else return @num_recs_added, @num_recs_input, @num_recs_updated, @rids, @update_id end end
Import data directly from an Excel file into a table The field names are expected to be on line 1 by default. By default, data will be read starting from row 2 and ending on the first empty row. Commas in field values will be converted to semi-colons. e.g. importFromExcel( @dbid, “my_spreadsheet.xls”, ‘h’ )
# File lib/QuickBaseClient.rb, line 4312 def importFromExcel( dbid,excelFilename,lastColumn = 'j',lastDataRow = 0,worksheetNumber = 1,fieldNameRow = 1,firstDataRow = 2,firstColumn = 'a') num_recs_imported = 0 if require 'win32ole' if FileTest.readable?( excelFilename ) getSchema( dbid ) excel = WIN32OLE::new( 'Excel.Application' ) workbook = excel.Workbooks.Open( excelFilename ) worksheet = workbook.Worksheets( worksheetNumber ) worksheet.Select fieldNames = nil rows = nil skipFirstRow = nil if fieldNameRow > 0 fieldNames = worksheet.Range("#{firstColumn}#{fieldNameRow}:#{lastColumn}#{fieldNameRow}")['Value'] skipFirstRow = true end if lastDataRow <= 0 lastDataRow = 1 while worksheet.Range("#{firstColumn}#{lastDataRow}")['Value'] lastDataRow += 1 end end if firstDataRow > 0 and lastDataRow >= firstDataRow rows = worksheet.Range("#{firstColumn}#{firstDataRow}:#{lastColumn}#{lastDataRow}")['Value'] end workbook.Close excel.Quit csvData = "" targetFieldIDs = [] if fieldNames and fieldNames.length > 0 fieldNames.each{ |fieldNameRow| fieldNameRow.each{ |fieldName| if fieldName fieldName.gsub!( ",", ";" ) #strip commas csvData << "#{fieldName}," targetFieldIDs << lookupFieldIDByName( fieldName ) else csvData << "," end } csvData[-1] = "\n" } end rows.each{ |row| row.each{ |cell| if cell cell = cell.to_s cell.gsub!( ",", ";" ) #strip commas csvData << "#{cell}," else csvData << "," end } csvData[-1] = "\n" } clist = targetFieldIDs.join( '.' ) num_recs_imported = importFromCSV( dbid, formatImportCSV( csvData ), clist, skipFirstRow ) else raise "importFromExcel: '#{excelFilename}' is not a readable file." end end num_recs_imported end
Add records from lines in a separated values text file, using a specified field name/value separator.
e.g. importSVFile( “contacts.txt”, “::”, “dhnju5y7”, [ “Name”, “Phone”, “Email” ] )
If targetFieldNames is not specified, the first line in the file must be a list of field names that match the values in subsequent lines.
If there are no commas in any of the field names or values, the file will be treated as if it were a CSV file and imported using the QuickBase
importFromCSV API call. Otherwise, records will be added using addRecord() for each line. Lines with the wrong number of fields will be skipped. Double-quoted fields can contain the field separator, e.g. f1,“f,2”,f3 Spaces will not be trimmed from the beginning or end of field values.
# File lib/QuickBaseClient.rb, line 4416 def importSVFile( filename, fieldSeparator = ",", dbid = @dbid, targetFieldNames = nil, validateLines = true ) num_recs_imported = 0 if FileTest.readable?( filename ) if dbid getSchema( dbid ) targetFieldIDs = [] if targetFieldNames and targetFieldNames.is_a?( Array ) targetFieldNames.each{ |fieldName| targetFieldIDs << lookupFieldIDByName( fieldName ) } return 0 if targetFieldIDs.length != targetFieldNames.length end useAddRecord = false invalidLines = [] validLines = [] linenum = 1 IO.foreach( filename ){ |line| if fieldSeparator != "," and line.index( "," ) useAddRecord = true end if linenum == 1 and targetFieldNames.nil? targetFieldNames = splitString( line, fieldSeparator ) targetFieldNames.each{ |fieldName| fieldName.strip! targetFieldIDs << lookupFieldIDByName( fieldName ) } return 0 if targetFieldIDs.length != targetFieldNames.length else fieldValues = splitString( line, fieldSeparator ) if !validateLines validLines[ linenum ] = fieldValues elsif validateLines and fieldValues.length == targetFieldIDs.length validLines[ linenum ] = fieldValues else invalidLines[ linenum ] = fieldValues end end linenum += 1 } if targetFieldIDs.length > 0 and validLines.length > 0 if useAddRecord validLines.each{ |line| clearFieldValuePairList targetFieldIDs.each_index{ |i| addFieldValuePair( nil, targetFieldIDs[i], nil, line[i] ) } addRecord( dbid, @fvlist ) num_recs_imported += 1 if @rid } else csvdata = "" validLines.each{ |line| if line csvdata << line.join( ',' ) csvdata << "\n" end } clist = targetFieldIDs.join( '.' ) num_recs_imported = importFromCSV( dbid, formatImportCSV( csvdata ), clist ) end end end end return num_recs_imported, invalidLines end
Import records from a text file in Tab-Separated-Values format.
# File lib/QuickBaseClient.rb, line 4399 def importTSVFile( filename, dbid = @dbid, targetFieldNames = nil, validateLines = true ) importSVFile( filename, "\t", dbid, targetFieldNames, validateLines ) end
API_InstallAppZip
# File lib/QuickBaseClient.rb, line 2841 def installAppZip( dbid ) @dbid = dbid sendRequest( :installAppZip ) return self if @chainAPIcalls @responseCode end
Returns whether a field will show an Average on reports.
# File lib/QuickBaseClient.rb, line 542 def isAverageField?(fieldName) does_average = lookupFieldPropertyByName(fieldName,"does_average") ret = does_average and does_average == "1" end
Returns whether a field ID is the ID for a built-in field
# File lib/QuickBaseClient.rb, line 554 def isBuiltInField?( fid ) fid.to_i < 6 end
Returns whether a request will return HTML
rather than XML.
# File lib/QuickBaseClient.rb, line 315 def isHTMLRequest?( api_Request ) ret = false case api_Request when :genAddRecordForm, :genResultsTable, :getRecordAsHTML ret = true end ret end
Returns whether a field ID is the ID for the key field in a QuickBase
table.
# File lib/QuickBaseClient.rb, line 548 def isRecordidField?( fid ) fields = lookupFieldsByType( "recordid" ) (fields and fields.last and fields.last.attributes[ "id" ] == fid) end
Returns whether a field will show a Total on reports.
# File lib/QuickBaseClient.rb, line 536 def isTotalField?(fieldName) does_total = lookupFieldPropertyByName(fieldName,"does_total") ret = does_total and does_total == "1" end
Returns whether a given string represents a valid QuickBase
field property.
# File lib/QuickBaseClient.rb, line 1060 def isValidFieldProperty?( property ) if @validFieldProperties.nil? @validFieldProperties = %w{ allow_new_choices allowHTML appears_by_default append_only blank_is_zero bold carrychoices comma_start cover_text currency_format currency_symbol decimal_places default_kind default_today default_today default_value display_dow display_graphic display_month display_relative display_time display_today display_user display_zone does_average does_total doesdatacopy exact fieldhelp find_enabled foreignkey format formula has_extension hours24 label max_versions maxlength nowrap num_lines required sort_as_given source_fid source_fieldname target_dbid target_dbname target_fid target_fieldname unique units use_new_window width } end ret = @validFieldProperties.include?( property ) end
Returns whether a given string represents a valid QuickBase
field type.
# File lib/QuickBaseClient.rb, line 1047 def isValidFieldType?( type ) @validFieldTypes ||= %w{ checkbox dblink date duration email file fkey float formula currency lookup multiuserid phone percent rating recordid text timeofday timestamp url userid icalendarbutton } @validFieldTypes.include?( type ) end
Loop through the list of Pages for an application
# File lib/QuickBaseClient.rb, line 3135 def iterateDBPages(dbid) listDBPages(dbid){|page| if page.is_a?( REXML::Element) and page.name == "page" @pageid = page.attributes["id"] @pagetype = page.attributes["type"] @pagename = page.text if page.has_text? @page = { "name" => @pagename, "id" => @pageid, "type" => @pagetype } yield @page end } end
Same as iterateRecords but with fields optionally filtered by Ruby regular expressions. e.g. iterateFilteredRecords( “dhnju5y7”, [{“Name” => “[A-E].+”},“Address”] ) { |values| puts values, values }
# File lib/QuickBaseClient.rb, line 3510 def iterateFilteredRecords( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) fields = [] regexp = {} fieldNames.each{|field| if field.is_a?(Hash) fields << field.keys[0] regexp[field.keys[0]] = field.values[0] elsif field.is_a?(String) fields << field end } regexp = nil if regexp.length == 0 iterateRecords(dbid,fields,query,qid,qname,clist,slist,fmt,options){|record| if regexp match = true fields.each{|field| if regexp[field] unless record[field] and record[field].match(regexp[field]) match = false break end end } yield record if match else yield record end } end
Get records from two or more tables and/or queries with the same value in a ‘join’ field and loop through the joined results. The ‘joinfield’ does not have to have the same name in each table. Fields with the same name in each table will be merged, with the value from the last table being assigned. This is similar to an SQL JOIN.
# File lib/QuickBaseClient.rb, line 3557 def iterateJoinRecords(tablesAndFields) raise "'iterateJoinRecords' must be called with a block." if not block_given? if tablesAndFields and tablesAndFields.is_a?(Array) # get all the records from QuickBase that we might need - fewer API calls is faster than processing extra data tables = [] numRecords = {} tableRecords = {} joinfield = {} tablesAndFields.each{|tableAndFields| if tableAndFields and tableAndFields.is_a?(Hash) if tableAndFields["dbid"] and tableAndFields["fields"] and tableAndFields["joinfield"] if tableAndFields["fields"].is_a?(Array) tables << tableAndFields["dbid"] joinfield[tableAndFields["dbid"]] = tableAndFields["joinfield"] tableAndFields["fields"] << tableAndFields["joinfield"] if not tableAndFields["fields"].include?(tableAndFields["joinfield"]) tableRecords[tableAndFields["dbid"]] = getAllValuesForFields( tableAndFields["dbid"], tableAndFields["fields"], tableAndFields["query"], tableAndFields["qid"], tableAndFields["qname"], tableAndFields["clist"], tableAndFields["slist"], "structured", tableAndFields["options"]) numRecords[tableAndFields["dbid"]] = tableRecords[tableAndFields["dbid"]][tableAndFields["fields"][0]].length else raise "'tableAndFields[\"fields\"]' must be an Array of fields to retrieve." end else raise "'tableAndFields' is missing one of 'dbid', 'fields' or 'joinfield'." end else raise "'tableAndFields' must be a Hash" end } numTables = tables.length # go through the records in the first table (0..(numRecords[tables[0]]-1)).each{|i| # get the value of the join field in each record of the first table joinfieldValue = tableRecords[tables[0]][joinfield[tables[0]]][i] # save the other tables' record indices of records containing the joinfield value tableIndices = [] (1..(numTables-1)).each{|tableNum| tableIndices[tableNum] = [] (0..(numRecords[tables[tableNum]]-1)).each{|j| if joinfieldValue == tableRecords[tables[tableNum]][joinfield[tables[tableNum]]][j] tableIndices[tableNum] << j end } } # if all the tables had at least one matching record, build a joined record and yield it buildJoinRecord = true (1..(numTables-1)).each{|tableNum| buildJoinRecord = false if not tableIndices[tableNum].length > 0 } if buildJoinRecord joinRecord = {} tableRecords[tables[0]].each_key{|field| joinRecord[field] = tableRecords[tables[0]][field][i] } # nested loops for however many tables we have currentIndex = [] numTables.times{ currentIndex << 0 } loop { (1..(numTables-1)).each{|tableNum| index = tableIndices[tableNum][currentIndex[tableNum]] tableRecords[tables[tableNum]].each_key{|field| joinRecord[field] = tableRecords[tables[tableNum]][field][index] } if currentIndex[tableNum] == tableIndices[tableNum].length-1 currentIndex[tableNum] = -1 else currentIndex[tableNum] += 1 end if tableNum == numTables-1 yield joinRecord end } finishLooping = true (1..(numTables-1)).each{|tableNum| finishLooping = false if currentIndex[tableNum] != -1 } break if finishLooping } end } else raise "'tablesAndFields' must be Array of Hashes of table query parameters." end end
Loop through a list of records returned from a query. Each record will contain all the fields with values formatted for readability by QuickBase
via API_GetRecordInfo.
# File lib/QuickBaseClient.rb, line 3853 def iterateRecordInfos(dbid, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil) getSchema(dbid) recordIDFieldName = lookupFieldNameFromID("3") fieldNames = getFieldNames fieldIDs = {} fieldNames.each{|name|fieldIDs[name] = lookupFieldIDByName(name)} iterateRecords(dbid, [recordIDFieldName], query, qid, qname, clist, slist, fmt, options){|r| getRecordInfo(dbid,r[recordIDFieldName]) fieldValues = {} fieldIDs.each{|k,v| fieldValues[k] = getFieldDataPrintableValue(v) fieldValues[k] ||= getFieldDataValue(v) } yield fieldValues } end
Loop through records returned from a query. Each record is a field+value Hash. e.g. iterateRecords( “dhnju5y7”, [“Name”,“Address”] ) { |values| puts values, values }
# File lib/QuickBaseClient.rb, line 3489 def iterateRecords( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) if block_given? queryResults = getAllValuesForFields(dbid,fieldNames,query,qid,qname,clist,slist,fmt,options) if queryResults numRecords = 0 numRecords = queryResults[fieldNames[0]].length if queryResults[fieldNames[0]] (0..(numRecords-1)).each{|recNum| recordHash = {} fieldNames.each{|fieldName| recordHash[fieldName]=queryResults[fieldName][recNum] } yield recordHash } end else raise "'iterateRecords' must be called with a block." end end
(The QuickBase
API does not supply a method for this.) Loop through summary records, like the records in a QuickBase
Summary report. Fields with ‘Total’ and ‘Average’ checked in the target table will be summed and/or averaged. Other fields with duplicate values will be merged into a single ‘record’. The results will be sorted by the merged fields, in ascending order. e.g. -
iterateSummaryRecords( "vavaa4sdd", ["Customer", "Amount"] ) {|record| puts "Customer: #{record['Customer']}, Amount #{record['Amount']} }
would print the total Amount for each Customer, sorted by Customer.
# File lib/QuickBaseClient.rb, line 3743 def iterateSummaryRecords( dbid, fieldNames,query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) getSchema(dbid) slist = "" summaryRecord = {} doesTotal = {} doesAverage = {} summaryField = {} fieldType = {} fieldNames.each{ |fieldName| fieldType[fieldName] = lookupFieldTypeByName(fieldName) isSummaryField = true doesTotal[fieldName] = isTotalField?(fieldName) doesAverage[fieldName] = isAverageField?(fieldName) if doesTotal[fieldName] summaryRecord["#{fieldName}:Total"] = 0 isSummaryField = false end if doesAverage[fieldName] summaryRecord["#{fieldName}:Average"] = 0 isSummaryField = false end if isSummaryField summaryField[fieldName] = true fieldID = lookupFieldIDByName(fieldName) slist << "#{fieldID}." end } slist[-1] = "" count = 0 iterateRecords( dbid, fieldNames, query, qid, qname, clist, slist, fmt, options) { |record| summaryFieldValuesHaveChanged = false fieldNames.each{ |fieldName| if summaryField[fieldName] and record[fieldName] != summaryRecord[fieldName] summaryFieldValuesHaveChanged = true break end } if summaryFieldValuesHaveChanged summaryRecord["Count"] = count fieldNames.each{|fieldName| if doesTotal[fieldName] summaryRecord["#{fieldName}:Total"] = formatFieldValue(summaryRecord["#{fieldName}:Total"],fieldType[fieldName]) end if doesAverage[fieldName] summaryRecord["#{fieldName}:Average"] = summaryRecord["#{fieldName}:Average"]/count if count > 0 summaryRecord["#{fieldName}:Average"] = formatFieldValue(summaryRecord["#{fieldName}:Average"],fieldType[fieldName]) end } yield summaryRecord count=0 summaryRecord = {} fieldNames.each{|fieldName| if doesTotal[fieldName] summaryRecord["#{fieldName}:Total"] = 0 end if doesAverage[fieldName] summaryRecord["#{fieldName}:Average"] = 0 end } end count += 1 fieldNames.each{|fieldName| if doesTotal[fieldName] summaryRecord["#{fieldName}:Total"] += record[fieldName].to_i end if doesAverage[fieldName] summaryRecord["#{fieldName}:Average"] += record[fieldName].to_i end if summaryField[fieldName] summaryRecord[fieldName] = record[fieldName] end } } summaryRecord["Count"] = count fieldNames.each{|fieldName| if doesTotal[fieldName] summaryRecord["#{fieldName}:Total"] = formatFieldValue(summaryRecord["#{fieldName}:Total"],fieldType[fieldName]) end if doesAverage[fieldName] summaryRecord["#{fieldName}:Average"] = summaryRecord["#{fieldName}:Average"]/count summaryRecord["#{fieldName}:Average"] = formatFieldValue(summaryRecord["#{fieldName}:Average"],fieldType[fieldName]) end } yield summaryRecord end
Get values from the same fields in two or more tables and/or queries and loop through the merged results. The merged records will be unique. This is similar to an SQL UNION.
# File lib/QuickBaseClient.rb, line 3676 def iterateUnionRecords(tables,fieldNames) raise "'iterateUnionRecords' must be called with a block." if not block_given? if tables and tables.is_a?(Array) if fieldNames and fieldNames.is_a?(Array) tableRecords = [] tables.each{|table| if table and table.is_a?(Hash) and table["dbid"] tableRecords << getAllValuesForFields( table["dbid"], fieldNames, table["query"], table["qid"], table["qname"], table["clist"], table["slist"], "structured", table["options"]) else raise "'table' must be a Hash that includes an entry for 'dbid'." end } else raise "'fieldNames' must be an Array of field names valid in all the tables." end else raise "'tables' must be an Array of Hashes." end usedRecords = {} tableRecords.each{|queryResults| if queryResults numRecords = 0 numRecords = queryResults[fieldNames[0]].length if queryResults[fieldNames[0]] (0..(numRecords-1)).each{|recNum| recordHash = {} fieldNames.each{|fieldName| recordHash[fieldName]=queryResults[fieldName][recNum] } if not usedRecords[recordHash.values.join] usedRecords[recordHash.values.join]=true yield recordHash end } end } end
API_ListDBPages
# File lib/QuickBaseClient.rb, line 2849 def listDBPages(dbid) @dbid = dbid sendRequest( :listDBPages ) @pages = getResponseValue( :pages ) return self if @chainAPIcalls if block_given? if @pages @pages.each{ |element| yield element } else yield nil end else @pages end end
Get a field’s base type using its name.
# File lib/QuickBaseClient.rb, line 1363 def lookupBaseFieldTypeByName( fieldName ) type = "" fid = lookupFieldIDByName( fieldName ) field = lookupField( fid ) if fid type = field.attributes[ "base_type" ] if field type end
Makes the table with the specified name the ‘active’ table, and returns the id from the table.
# File lib/QuickBaseClient.rb, line 907 def lookupChdbid( tableName, dbid=nil ) getSchema(dbid) if dbid unmodifiedTableName = tableName.dup @chdbid = findElementByAttributeValue( @chdbids, "name", formatChdbidName( tableName ) ) if @chdbid @dbid = @chdbid.text return @dbid end if @chdbids chdbidArray = findElementsByAttributeName( @chdbids, "name" ) chdbidArray.each{ |chdbid| if chdbid.has_text? dbid = chdbid.text getSchema( dbid ) name = getResponseElement( "table/name" ) if name and name.has_text? and name.text.downcase == unmodifiedTableName.downcase @chdbid = chdbid @dbid = dbid return @dbid end end } end nil end
Returns the XML element for a field definition. getSchema() or doQuery() should be called before this.
# File lib/QuickBaseClient.rb, line 753 def lookupField( fid ) @field = findElementByAttributeValue( @fields, "id", fid ) end
Returns the XML element for a field returned by a getRecordInfo call.
# File lib/QuickBaseClient.rb, line 758 def lookupFieldData( fid ) @field_data = nil if @field_data_list @field_data_list.each{ |field| if field and field.is_a?( REXML::Element ) and field.has_elements? fieldid = field.elements[ "fid" ] if fieldid and fieldid.has_text? and fieldid.text == fid.to_s @field_data = field end end } end @field_data end
Gets the ID for a field using the QuickBase
field label. getSchema() or doQuery() should be called before this if you don’t supply the dbid.
# File lib/QuickBaseClient.rb, line 801 def lookupFieldIDByName( fieldName, dbid=nil ) getSchema(dbid) if dbid ret = nil if @fields @fields.each_element_with_attribute( "id" ){ |f| if f.name == "field" and f.elements[ "label" ].text.downcase == fieldName.downcase ret = f.attributes[ "id" ].dup break end } end ret end
Returns the name of field given an “fid” XML element.
# File lib/QuickBaseClient.rb, line 491 def lookupFieldName( element ) name = "" if element and element.is_a?( REXML::Element ) name = element.name if element.name == "f" and @fields fid = element.attributes[ "id" ] field = lookupField( fid ) if fid label = field.elements[ "label" ] if field name = label.text if label end end name end
Gets a field name (i.e. QuickBase
field label) using a field ID. getSchema() or doQuery() should be called before this if you don’t supply the dbid.
# File lib/QuickBaseClient.rb, line 479 def lookupFieldNameFromID( fid, dbid=nil ) getSchema(dbid) if dbid name = nil if @fields field = lookupField( fid ) if fid label = field.elements[ "label" ] if field name = label.text if label end name end
Returns the value of a field property, or nil.
# File lib/QuickBaseClient.rb, line 524 def lookupFieldPropertyByName( fieldName, property ) theproperty = nil if isValidFieldProperty?(property) fid = lookupFieldIDByName( fieldName ) field = lookupField( fid ) if fid theproperty = field.elements[ property ] if field theproperty = theproperty.text if theproperty and theproperty.has_text? end theproperty end
Returns a QuickBase
field type, given an XML “fid” element.
# File lib/QuickBaseClient.rb, line 506 def lookupFieldType( element ) type = "" if element and element.is_a?( REXML::Element ) if element.name == "f" and @fields fid = element.attributes[ "id" ] field = lookupField( fid ) if fid type = field.attributes[ "field_type" ] if field end end type end
Get a field’s type using its name.
# File lib/QuickBaseClient.rb, line 1372 def lookupFieldTypeByName( fieldName ) type = "" fid = lookupFieldIDByName( fieldName ) field = lookupField( fid ) if fid type = field.attributes[ "field_type" ] if field type end
Returns an array of XML field elements matching a QuickBase
field type.
# File lib/QuickBaseClient.rb, line 519 def lookupFieldsByType( type ) findElementsByAttributeValue( @fields, "field_type", type ) end
Returns the XML element for a query with the specified ID. getSchema() or doQuery() should be called before this if you don’t supply the dbid.
# File lib/QuickBaseClient.rb, line 879 def lookupQuery( qid, dbid=nil ) getSchema(dbid) if dbid @query = findElementByAttributeValue( @queries, "id", qid ) end
Returns the XML element for a query with the specified ID. getSchema() or doQuery() should be called before this if you don’t supply the dbid.
# File lib/QuickBaseClient.rb, line 886 def lookupQueryByName( name, dbid=nil ) getSchema(dbid) if dbid if @queries @queries.each_element_with_attribute( "id" ){|q| if q.name == "query" and q.elements["qyname"].text.downcase == name.downcase return q end } end nil end
Returns the XML element for a record with the specified ID.
# File lib/QuickBaseClient.rb, line 873 def lookupRecord( rid ) @record = findElementByAttributeValue( @records, "id", rid ) end
Create a CSV file using the records for a Report.
# File lib/QuickBaseClient.rb, line 4554 def makeCSVFileForReport(filename,dbid=@dbid,query=nil,qid=nil,qname=nil) csv = getCSVForReport(dbid,query,qid,qname) File.open(filename,"w"){|f|f.write(csv || "")} end
Make a CSV file using the results of a query. Specify a different separator in the second paramater. Fields containing the separator will be double-quoted.
e.g. makeSVFile( “contacts.txt”, “t”, nil ) e.g. makeSVFile( “contacts.txt”, “,”, “dhnju5y7”, nil, nil, “List Changes” )
# File lib/QuickBaseClient.rb, line 4496 def makeSVFile( filename, fieldSeparator = ",", dbid = @dbid, query = nil, qid = nil, qname = nil ) File.open( filename, "w" ) { |file| if dbid doQuery( dbid, query, qid, qname ) end if @records and @fields # ------------- write field names on first line ---------------- output = "" fieldNamesBlock = proc { |element| if element.is_a?(REXML::Element) and element.name == "label" and element.has_text? output << "#{element.text}#{fieldSeparator}" end } processChildElements( @fields, true, fieldNamesBlock ) output << "\n" output.sub!( "#{fieldSeparator}\n", "\n" ) file.write( output ) # ------------- write records ---------------- output = "" valuesBlock = proc { |element| if element.is_a?(REXML::Element) if element.name == "record" if output.length > 1 output << "\n" output.sub!( "#{fieldSeparator}\n", "\n" ) file.write( output ) end output = "" elsif element.name == "f" if element.has_text? text = element.text text.gsub!("<BR/>","\n") text = "\"#{text}\"" if text.include?( fieldSeparator ) output << "#{text}#{fieldSeparator}" else output << "#{fieldSeparator}" end end end } processChildElements( @records, false, valuesBlock ) if output.length > 1 output << "\n" output.sub!( "#{fieldSeparator}\n", "\n" ) file.write( output ) output = "" end end } end
Find the highest value for one or more fields in the records returned by a query. e.g. maximumsHash = max(“dfdfafff”,[“Date Sent”,“Quantity”,“Part Name”])
# File lib/QuickBaseClient.rb, line 4000 def max( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) max = {} hasValues = false iterateRecords(dbid,fieldNames,query,qid,qname,clist,slist,fmt,options){|record| fieldNames.each{|field| value = record[field] if value baseFieldType = lookupBaseFieldTypeByName(field) case baseFieldType when "int32","int64","bool" value = record[field].to_i when "float" value = record[field].to_f end end if max[field].nil? or (value and value > max[field]) max[field] = value hasValues = true end } } max = nil if not hasValues max end
Enables alternative syntax for processing data using id values or xml element names. E.g:
qbc.bcdcajmrh.qid_1.printChildElements(qbc.records)
-
prints the records returned by query 1 from table bcdcajmrh
puts qbc.bcdcajmrf.xml_desc
-
get the description from the bcdcajmrf application
puts qbc.dbid_8emtadvk.rid_24105.fid_6
-
print field 6 from record 24105 in table 8emtadvk
# File lib/QuickBaseClient.rb, line 667 def method_missing(missing_method_name, *missing_method_args) method_s = missing_method_name.to_s if method_s.match(/dbid_.+/) if QuickBase::Misc.isDbidString?(method_s.sub("dbid_","")) getSchema(method_s.sub("dbid_","")) end elsif @dbid and method_s.match(/rid_[0-9]+/) _setActiveRecord(method_s.sub("rid_","")) @fieldValue = @field_data_list elsif @dbid and method_s.match(/qid_[0-9]+/) doQuery(@dbid,nil,method_s.sub("qid_","")) elsif @dbid and method_s.match(/fid_[0-9]+/) if @field_data_list @fieldValue = getFieldDataValue(method_s.sub("fid_","")) else lookupField(method_s.sub("fid_","")) end elsif @dbid and method_s.match(/pageid_[0-9]+/) _getDBPage(method_s.sub("pageid_","")) elsif @dbid and method_s.match(/userid_.+/) _getUserRole(method_s.sub("userid_","")) elsif @dbid and @rid and @fid and method_s.match(/vid_[0-9]+/) downLoadFile( @dbid, @rid, @fid, method_s.sub("vid_","") ) elsif @dbid and method_s.match(/import_[0-9]+/) _runImport(method_s.sub("import_","")) elsif @qdbapi and method_s.match(/xml_.+/) if missing_method_args and missing_method_args.length > 0 @fieldValue = @qdbapi.send(method_s.sub("xml_",""),missing_method_args) else @fieldValue = @qdbapi.send(method_s.sub("xml_","")) end elsif QuickBase::Misc.isDbidString?(method_s) getSchema(method_s) else raise "'#{method_s}' is not a valid method in the QuickBase::Client class." end return @fieldValue if @fieldValue.is_a?(REXML::Element) # chain XML lookups return @fieldValue if @fieldValue.is_a?(String) # assume we just want a field value self # otherwise, allows chaining of all above end
Find the lowest value for one or more fields in the records returned by a query. e.g. minimumsHash = min(“dfdfafff”,[“Date Sent”,“Quantity”,“Part Name”])
# File lib/QuickBaseClient.rb, line 3973 def min( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) min = {} hasValues = false iterateRecords(dbid,fieldNames,query,qid,qname,clist,slist,fmt,options){|record| fieldNames.each{|field| value = record[field] if value baseFieldType = lookupBaseFieldTypeByName(field) case baseFieldType when "int32","int64","bool" value = record[field].to_i when "float" value = record[field].to_f end end if min[field].nil? or (value and value < min[field]) min[field] = value hasValues = true end } } min = nil if not hasValues min end
API_obstatus: get the status of the QuickBase
server.
# File lib/QuickBaseClient.rb, line 2707 def obStatus sendRequest( :obStatus ) @serverVersion = getResponseElement("version") @serverUsers = getResponseElement("users") @serverGroups = getResponseElement("groups") @serverDatabases = getResponseElement("databases") @serverUptime = getResponseElement("uptime") @serverUpdays = getResponseElement("updays") @serverStatus = { "version" => @serverVersion.text, "users" => @serverUsers.text, "groups" => @serverGroups.text, "databases" => @serverDatabases.text, "uptime" => @serverUptime.text, "updays" => @serverUpdays.text } end
Reset appropriate member variables after a different table is accessed.
# File lib/QuickBaseClient.rb, line 1579 def onChangedDbid _getDBInfo _getSchema resetrid resetfid end
Called by processResponse to put the XML from QuickBase
into a DOM tree using the REXML
module that comes with Ruby.
# File lib/QuickBaseClient.rb, line 409 def parseResponseXML( xml ) if xml xml.gsub!( "\r", "" ) if @ignoreCR and @ignoreCR == true xml.gsub!( "\n", "" ) if @ignoreLF and @ignoreLF == true xml.gsub!( "\t", "" ) if @ignoreTAB and @ignoreTAB == true xml.gsub!( "<BR/>", "<BR/>" ) if @escapeBR @qdbapi = @responseXMLdoc = REXML::Document.new( xml ) end end
Given an array of two numbers, return the second number as a percentage of the first number.
# File lib/QuickBaseClient.rb, line 4141 def percent( inputValues ) raise "'inputValues' must not be nil" if inputValues.nil? raise "'inputValues' must be an Array" if not inputValues.is_a?(Array) raise "'inputValues' must have at least two elements" if inputValues.length < 2 total = inputValues[0].to_f total = 1.0 if total == 0.00 value = inputValues[1].to_f ((value/total)*100) end
Returns whether to prepend ‘API_’ to request string
# File lib/QuickBaseClient.rb, line 325 def prependAPI?( request ) ret = true ret = false if request.to_s.include?("API_") or request.to_s.include?("QBIS_") ret end
Recursive method to print a simplified (yaml-like) tree of the XML returned by QuickBase
.
Translates field IDs into field names. Very useful during debugging.
# File lib/QuickBaseClient.rb, line 583 def printChildElements( element, indent = 0 ) indentation = "" indent.times{ indentation << " " } if indent > 0 if element and element.is_a?( REXML::Element ) and element.has_elements? attributes = getAttributeString( element ) name = lookupFieldName( element ) puts "#{indentation}#{name} #{attributes}:" element.each { |element| if element.is_a?( REXML::Element ) and element.has_elements? printChildElements( element, (indent+1) ) elsif element.is_a?( REXML::Element ) and element.has_text? attributes = getAttributeString( element ) name = lookupFieldName( element ) text = formatFieldValue( element.text, lookupFieldType( element ) ) puts " #{indentation}#{name} #{attributes} = #{text}" end } elsif element and element.is_a?( Array ) element.each{ |e| printChildElements( e ) } end self end
Prints the error info, if any, for the last request sent to QuickBase
.
# File lib/QuickBaseClient.rb, line 371 def printLastError if @lastError puts puts "Last error: ------------------------------------------" p @lastError end self end
Called by sendRequest if @printRequestsAndResponses is true
# File lib/QuickBaseClient.rb, line 352 def printRequest( url, headers, xml ) puts puts "Request: -------------------------------------------" p url if url p headers if headers p xml if xml self end
Called by sendRequest if @printRequestsAndResponses is true
# File lib/QuickBaseClient.rb, line 362 def printResponse( code, xml ) puts puts "Response: ------------------------------------------" p code if code p xml if xml self end
Recursive method to process leaf and (optionally) parent elements of any XML element returned by QuickBase
.
# File lib/QuickBaseClient.rb, line 640 def processChildElements( element, leafElementsOnly, block ) if element if element.is_a?( Array ) element.each{ |e| processChildElements( e, leafElementsOnly, block ) } elsif element.is_a?( REXML::Element ) and element.has_elements? block.call( element ) if not leafElementsOnly element.each{ |e| if e.is_a?( REXML::Element ) and e.has_elements? processChildElements( e, leafElementsOnly, block ) else block.call( e ) end } end end end
# File lib/QuickBaseClient.rb, line 3939 def processRESTFieldNameOrRecordKeyRequest(dbid,fieldNameOrRecordKey) returnvalue = "" requestType = "" getSchema(dbid) fieldNames = getFieldNames if fieldNames.include?(fieldNameOrRecordKey) # name of a field in the table requestType = "fieldName" iterateRecordInfos(dbid){|r| returnvalue << "#{fieldNameOrRecordKey}:#{r[fieldNameOrRecordKey]}\n" if r } elsif @key_fid # key field value requestType = "keyFieldValue" iterateRecordInfos(dbid,"{'#{@key_fid}'.EX.'#{fieldNameOrRecordKey}'}"){|r| r.each{|k,v| returnvalue << "#{k}:#{v}\n"} if r } elsif fieldNameOrRecordKey.match(/[0-9]+/) # guess that this is a Record #ID value requestType = "recordID" iterateRecordInfos(dbid,"{'3'.EX.'#{fieldNameOrRecordKey}'}"){|r| r.each{|k,v| returnvalue << "#{k}:#{v}\n"} if r } else # guess that the first non-built-in field is a secondary non-numeric key field requestType = "field6" iterateRecordInfos(dbid,"{'6'.TV.'#{fieldNameOrRecordKey}'}"){|r| if r returnvalue << "Record:\n" r.each{|k,v| returnvalue << "#{k}:#{v}\n"} end } end return returnvalue, requestType end
Returns table or record values using REST syntax. e.g. - puts processRESTRequest(“8emtadvk/24105”) # prints record 24105 from Community Forum puts processRESTRequest(“8emtadvk”) # prints name of table with dbid of ‘8emtadvk’ puts qbc.processRESTRequest(“6ewwzuuj/Function Name”) # prints list of QuickBase
Functions
# File lib/QuickBaseClient.rb, line 3874 def processRESTRequest(requestString) ret = nil request = requestString.dup request.gsub!("//","ESCAPED/") requestParts = request.split('/') requestParts.each{|part| part.gsub!("ESCAPED/","//") } applicationName = nil applicationDbid= nil tableName = nil tableDbid = nil requestType = "" requestParts.each_index{|i| if i == 0 dbid = findDBByName(requestParts[0].dup) if dbid applicationDbid= dbid.dup # app/ applicationName = requestParts[0].dup ret = "dbid:#{applicationDbid}" elsif QuickBase::Misc.isDbidString?(requestParts[0].dup) and getSchema(requestParts[0].dup) tableDbid = requestParts[0].dup # dbid/ tableName = getTableName(tableDbid) ret = "table:#{tableName}" else ret = "Unable to process '#{requestParts[0].dup}' part of '#{requestString}'." end elsif i == 1 if applicationDbid getSchema(applicationDbid) tableDbid = lookupChdbid(requestParts[1].dup) if tableDbid # app/chdbid/ tableName = requestParts[1].dup ret = "dbid:#{tableDbid}" else getSchema(applicationDbid.dup) tableDbid = lookupChdbid(applicationName.dup) if tableDbid # app+appchdbid/ tableName = applicationName ret, requestType = processRESTFieldNameOrRecordKeyRequest(tableDbid,requestParts[1].dup) else ret = "Unable to process '#{requestParts[1].dup}' part of '#{requestString}'." end end elsif tableDbid ret, requestType = processRESTFieldNameOrRecordKeyRequest(tableDbid,requestParts[1].dup) else ret = "Unable to process '#{requestParts[1].dup}' part of '#{requestString}'." end elsif (i==2 or i == 3) and ["keyFieldValue","recordID"].include?(requestType) fieldValues = ret.split(/\n/) fieldValues.each{|fieldValue| if fieldValue.index("#{requestParts[i].dup}:") == 0 ret = fieldValue.gsub("#{requestParts[i].dup}:","") break end } elsif i == 2 and tableDbid ret, requestType = processRESTFieldNameOrRecordKeyRequest(tableDbid,requestParts[2].dup) else ret = "Unable to process '#{requestString}'." end } ret end
Except for requests that return HTML
, processes the XML responses returned from QuickBase
.
# File lib/QuickBaseClient.rb, line 381 def processResponse( responseXML ) fire( "onProcessResponse" ) parseResponseXML( responseXML ) @ticket ||= getResponseValue( :ticket ) @udata = getResponseValue( :udata ) getErrorInfoFromResponse end
API_ProvisionUser
# File lib/QuickBaseClient.rb, line 2871 def provisionUser( dbid, roleid, email, fname, lname ) @dbid, @roleid, @email, @fname, @lname = dbid, roleid, email, fname, lname xmlRequestData = toXML( :roleid, @roleid) xmlRequestData << toXML( :email, @email ) xmlRequestData << toXML( :fname, @fname ) xmlRequestData << toXML( :lname, @lname ) sendRequest( :provisionUser, xmlRequestData ) @userid = getResponseValue( :userid ) return self if @chainAPIcalls @userid end
API_PurgeRecords
# File lib/QuickBaseClient.rb, line 2891 def purgeRecords( dbid, query = nil, qid = nil, qname = nil ) @dbid = dbid xmlRequestData = getQueryRequestXML( query, qid, qname ) sendRequest( :purgeRecords, xmlRequestData ) @num_records_deleted = getResponseValue( :num_records_deleted ) return self if @chainAPIcalls @num_records_deleted end
Remove the file from a File Attachment field in an existing record. e.g. removeFileAttachment( “bdxxxibz4”, “6”, “Document” )
# File lib/QuickBaseClient.rb, line 4634 def removeFileAttachment( dbid, rid , fileAttachmentFieldName ) updateFile( dbid, rid, "delete", fileAttachmentFieldName ) end
API_RemoveUserFromRole
# File lib/QuickBaseClient.rb, line 2905 def removeUserFromRole( dbid, userid, roleid ) @dbid, @userid, @roleid = dbid, userid, roleid xmlRequestData = toXML( :userid, @userid ) xmlRequestData << toXML( :roleid, @roleid ) sendRequest( :removeUserFromRole, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
API_RenameApp
# File lib/QuickBaseClient.rb, line 2921 def renameApp( dbid, newappname ) @dbid, @newappname = dbid, newappname xmlRequestData = toXML( :newappname , @newappname ) sendRequest( :renameApp, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
Replaces a field value in the list of fields to be set by the next addRecord() or editRecord() call to QuickBase
.
# File lib/QuickBaseClient.rb, line 1171 def replaceFieldValuePair( name, fid, filename, value ) if @fvlist name = name.downcase if name name = name.gsub( /\W/, "_" ) if name @fvlist.each_index{|i| if (name and @fvlist[i].include?("<field name='#{name}'")) or (fid and @fvlist[i].include?("<field fid='#{fid}'")) @fvlist[i] = FieldValuePairXML.new( self, name, fid, filename, value ).to_s break end } end @fvlist end
Resets error info before QuickBase
requests are sent.
# File lib/QuickBaseClient.rb, line 280 def resetErrorInfo @errcode = "0" @errtext = "" @errdetail = "" @lastError = "" @requestSucceeded = true self end
Set the @fid (‘active’ field ID) member variable to nil.
# File lib/QuickBaseClient.rb, line 1574 def resetfid @fid = nil end
Set the @rid (‘active’ record ID) member variable to nil.
# File lib/QuickBaseClient.rb, line 1569 def resetrid @rid = nil end
API_RunImport
# File lib/QuickBaseClient.rb, line 2936 def runImport( dbid, id ) @dbid, @id = dbid, id xmlRequestData = toXML( :id , @id ) sendRequest( :runImport, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
API_SendInvitation
# File lib/QuickBaseClient.rb, line 2951 def sendInvitation( dbid, userid, usertext = "Welcome to my application!" ) @dbid, @userid, @usertext = dbid, userid, usertext xmlRequestData = toXML( :userid, @userid ) xmlRequestData << toXML( :usertext, @usertext ) sendRequest( :sendInvitation, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
Sends requests to QuickBase
and processes the reponses.
# File lib/QuickBaseClient.rb, line 204 def sendRequest( api_Request, xmlRequestData = nil ) fire( "onSendRequest" ) resetErrorInfo # set up the request getDBforRequestURL( api_Request ) getAuthenticationXMLforRequest( api_Request ) isHTMLRequest = isHTMLRequest?( api_Request ) api_Request = "API_" + api_Request.to_s if prependAPI?( api_Request ) xmlRequestData << toXML( :udata, @udata ) if @udata and @udata.length > 0 xmlRequestData << toXML( :rdr, @rdr ) if @rdr and @rdr.length > 0 xmlRequestData << toXML( :xsl, @xsl ) if @xsl and @xsl.length > 0 xmlRequestData << toXML( :encoding, @encoding ) if @encoding and @encoding.length > 0 if xmlRequestData @requestXML = toXML( :qdbapi, @authenticationXML + xmlRequestData ) else @requestXML = toXML( :qdbapi, @authenticationXML ) end @requestHeaders = @standardRequestHeaders @requestHeaders["Content-Length"] = "#{@requestXML.length}" @requestHeaders["QUICKBASE-ACTION"] = api_Request @requestURL = "#{@qbhost}#{@dbidForRequestURL}" printRequest( @requestURL, @requestHeaders, @requestXML ) if @printRequestsAndResponses @logger.logRequest( @dbidForRequestURL, api_Request, @requestXML ) if @logger begin # send the request if USING_HTTPCLIENT response = @httpConnection.post( @requestURL, @requestXML, @requestHeaders ) @responseCode = response.status @responseXML = response.content else if Net::HTTP.version_1_2? response = @httpConnection.post( @requestURL, @requestXML, @requestHeaders ) @responseCode = response.code @responseXML = response.body else @responseCode, @responseXML = @httpConnection.post( @requestURL, @requestXML, @requestHeaders ) end end printResponse( @responseCode, @responseXML ) if @printRequestsAndResponses if not isHTMLRequest processResponse( @responseXML ) end @logger.logResponse( @lastError, @responseXML ) if @logger fireDBChangeEvents rescue Net::HTTPBadResponse => error @lastError = "Bad HTTP Response: #{error}" rescue Net::HTTPHeaderSyntaxError => error @lastError = "Bad HTTP header syntax: #{error}" rescue StandardError => error @lastError = "Error processing #{api_Request} request: #{error}" end @requestSucceeded = ( @errcode == "0" and @lastError == "" ) fire( @requestSucceeded ? "onRequestSucceeded" : "onRequestFailed" ) if @stopOnError and !@requestSucceeded raise @lastError end end
Set the active database and record for subsequent method calls.
# File lib/QuickBaseClient.rb, line 3203 def setActiveRecord( dbid, rid ) if dbid and rid getRecordInfo( dbid, rid ) end @rid end
Set the active database table subsequent method calls.
# File lib/QuickBaseClient.rb, line 3198 def setActiveTable( dbid ) @dbid = dbid end
API_SetAppData
# File lib/QuickBaseClient.rb, line 2967 def setAppData( dbid, appdata ) @dbid, @appdata = dbid, appdata xmlRequestData = toXML( :appdata , @appdata ) sendRequest( :setAppData ) return self if @chainAPIcalls @appdata end
API_SetDBvar
# File lib/QuickBaseClient.rb, line 2982 def setDBvar( dbid, varname, value ) @dbid, @varname, @value = dbid, varname, value xmlRequestData = toXML( :varname, @varname ) xmlRequestData << toXML( :value, @value ) sendRequest( :setDBvar, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
API_SetFieldProperties
# File lib/QuickBaseClient.rb, line 2998 def setFieldProperties( dbid, properties, fid ) @dbid, @properties, @fid = dbid, properties, fid if @properties and @properties.is_a?( Hash ) xmlRequestData = toXML( :fid, @fid ) @properties.each{ |key, value| if isValidFieldProperty?( key ) xmlRequestData << toXML( key, value ) else raise "setFieldProperties: Invalid field property '#{key}'. Valid properties are " + @validFieldProperties.join( "," ) end } sendRequest( :setFieldProperties, xmlRequestData ) else raise "setFieldProperties: @properties is not a Hash of key/value pairs" end return self if @chainAPIcalls @requestSucceeded end
Change a named field’s value in the active record. e.g. setFieldValue( “Location”, “Miami” )
# File lib/QuickBaseClient.rb, line 3213 def setFieldValue( fieldName, fieldValue, dbid = nil, rid = nil, key =nil ) @dbid ||= dbid @rid ||= rid @key ||= key if @dbid and (@rid or @key) clearFieldValuePairList addFieldValuePair( fieldName, nil, nil, fieldValue ) editRecord( @dbid, @rid, @fvlist, nil, nil, nil, nil, nil, @key ) end end
Set several named fields’ values. Will modify the active record if there is one. e.g. setFieldValues( {“Location” => “Miami”, “Phone” => “343-4567” } )
# File lib/QuickBaseClient.rb, line 3226 def setFieldValues( fields, editRecord=true ) if fields.is_a?(Hash) clearFieldValuePairList fields.each{ |fieldName,fieldValue| addFieldValuePair( fieldName, nil, nil, fieldValue ) } if editRecord and @dbid and (@rid or @key) editRecord( @dbid, @rid, @fvlist, nil, nil, nil, nil, nil, @key ) end end end
Initializes the connection to QuickBase
.
# File lib/QuickBaseClient.rb, line 154 def setHTTPConnection( useSSL, org = "www", domain = "quickbase", proxy_options = nil ) @useSSL = useSSL @org = org @domain = domain if USING_HTTPCLIENT if proxy_options @httpConnection = HTTPClient.new( "#{proxy_options["proxy_server"]}:#{proxy_options["proxy_port"] || useSSL ? "443" : "80"}" ) @httpConnection.set_auth(proxy_options["proxy_server"], proxy_options["proxy_user"], proxy_options["proxy_password"]) else @httpConnection = HTTPClient.new end else if proxy_options @httpProxy = Net::HTTP::Proxy(proxy_options["proxy_server"], proxy_options["proxy_port"], proxy_options["proxy_user"], proxy_options["proxy_password"]) @httpConnection = @httpProxy.new( "#{@org}.#{@domain}.com", useSSL ? 443 : 80) else @httpConnection = Net::HTTP.new( "#{@org}.#{@domain}.com", useSSL ? 443 : 80 ) end @httpConnection.use_ssl = useSSL @httpConnection.verify_mode = OpenSSL::SSL::VERIFY_NONE end end
Initializes the connection to QuickBase
and sets the QuickBase
URL and port to use for requests.
# File lib/QuickBaseClient.rb, line 192 def setHTTPConnectionAndqbhost( useSSL, org = "www", domain = "quickbase", proxy_options = nil ) setHTTPConnection( useSSL, org, domain, proxy_options ) setqbhost( useSSL, org, domain ) end
API_SetKeyField
# File lib/QuickBaseClient.rb, line 3027 def setKeyField( dbid, fid ) @dbid, @fid = dbid, fid xmlRequestData = toXML( :fid, @fid ) sendRequest( :setKeyField, xmlRequestData ) return self if @chainAPIcalls @requestSucceeded end
Set the instance of a QuickBase::Logger
to be used by QuickBase::Client
. Closes the open log file if necessary.
# File lib/QuickBaseClient.rb, line 1625 def setLogger( logger ) if logger if logger.is_a?( Logger ) if @logger and @logger != logger @logger.closeLogFile() end @logger = logger end else @logger.closeLogFile() if @logger @logger = nil end end
Sets the QuickBase
URL and port to use for requests.
# File lib/QuickBaseClient.rb, line 183 def setqbhost( useSSL, org = "www", domain = "quickbase" ) @useSSL = useSSL @org = org @domain = domain @qbhost = useSSL ? "https://#{@org}.#{@domain}.com:443" : "http://#{@org}.#{@domain}.com" @qbhost end
API_SignOut
# File lib/QuickBaseClient.rb, line 3042 def signOut sendRequest( :signOut ) @ticket = @username = @password = nil return self if @chainAPIcalls @requestSucceeded end
Converts a string into an array, given a field separator. ‘“’ followed by the field separator are treated the same way as just the field separator.
# File lib/QuickBaseClient.rb, line 1500 def splitString(string, fieldSeparator = ",") CSV.parse(string, col_sep: fieldSeparator).shift end
Subscribe to a specified event published by QuickBase::Client
.
# File lib/QuickBaseClient.rb, line 1598 def subscribe( event, handler ) @events = %w{ onSendRequest onProcessResponse onSetActiveTable onRequestSucceeded onRequestFailed onSetActiveRecord onSetActiveField } if @events.nil? if @events.include?( event ) if handler and handler.is_a?( EventHandler ) if @eventSubscribers.nil? @eventSubscribers = {} end if not @eventSubscribers.include?( event ) @eventSubscribers[ event ] = [] end if not @eventSubscribers[ event ].include?( handler ) @eventSubscribers[ event ] << handler end else raise "subscribe: 'handler' must be a class derived from QuickBase::EventHandler." end else raise "subscribe: invalid event '#{event}'. Valid events are #{@events.sort.join( ', ' )}." end end
Returns the sum of the values for one or more fields in the records returned by a query. e.g. sumsHash = sum(“dfdfafff”,[“Date Sent”,“Quantity”,“Part Name”])
# File lib/QuickBaseClient.rb, line 4045 def sum( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil ) sum = {} hasValues = false iterateRecords(dbid,fieldNames,query,qid,qname,clist,slist,fmt,options){|record| fieldNames.each{|field| value = record[field] if value baseFieldType = lookupBaseFieldTypeByName(field) case baseFieldType when "int32","int64","bool" value = record[field].to_i when "float" value = record[field].to_f end if sum[field].nil? sum[field] = value else sum[field] = sum[field] + value end hasValues = true end } } sum = nil if not hasValues sum end
Builds the XML for a specific item included in a request to QuickBase
.
# File lib/QuickBaseClient.rb, line 1037 def toXML( tag, value = nil ) if value ret = "<#{tag}>#{value}</#{tag}>" else ret = "<#{tag}/>" end ret end
Turns program stack tracing on or off.
If followed by a block, the tracing will be toggled on or off at the end of the block.
# File lib/QuickBaseClient.rb, line 333 def toggleTraceInfo( showTrace ) if showTrace # this will print a very large amount of stuff set_trace_func proc { |event, file, line, id, binding, classname| printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname } if block_given? yield set_trace_func nil end else set_trace_func nil if block_given? yield set_trace_func proc { |event, file, line, id, binding, classname| printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname } end end self end
Update the file attachment in an existing record in a table. Additional field values can optionally be set. e.g. updateFile( “dhnju5y7”, “6”, “contacts.txt”, “Contacts File”, { “Notes” => “#{Time.now}” }
# File lib/QuickBaseClient.rb, line 4612 def updateFile( dbid, rid, filename, fileAttachmentFieldName, additionalFieldsToSet = nil ) if dbid and rid and filename and fileAttachmentFieldName clearFieldValuePairList addFieldValuePair( fileAttachmentFieldName, nil, filename, nil ) if additionalFieldsToSet and additionalFieldsToSet.is_a?( Hash ) additionalFieldsToSet.each{ |fieldName,fieldValue| addFieldValuePair( fieldName, nil, nil, fieldValue ) } end return editRecord( dbid, rid, @fvlist ) end nil end
Upload a file into a new record in a table. Additional field values can optionally be set. e.g. uploadFile( “dhnju5y7”, “contacts.txt”, “Contacts File”, { “Notes” => “#{Time.now}” }
# File lib/QuickBaseClient.rb, line 4567 def uploadFile( dbid, filename, fileAttachmentFieldName, additionalFieldsToSet = nil ) if dbid and filename and fileAttachmentFieldName clearFieldValuePairList addFieldValuePair( fileAttachmentFieldName, nil, filename, nil ) if additionalFieldsToSet and additionalFieldsToSet.is_a?( Hash ) additionalFieldsToSet.each{ |fieldName,fieldValue| addFieldValuePair( fieldName, nil, nil, fieldValue ) } end return addRecord( dbid, @fvlist ) end nil end
Add a File Attachment into a new record in a table, using a string containing the file contents. Additional field values can optionally be set. e.g. uploadFile( “dhnju5y7”, “contacts.txt”, “fred: 1-222-333-4444”, “Contacts File”, { “Notes” => “#{Time.now}” }
# File lib/QuickBaseClient.rb, line 4584 def uploadFileContents( dbid, filename, fileContents, fileAttachmentFieldName, additionalFieldsToSet = nil ) if dbid and filename and fileAttachmentFieldName clearFieldValuePairList addFieldValuePair( fileAttachmentFieldName, nil, filename, fileContents ) if additionalFieldsToSet and additionalFieldsToSet.is_a?( Hash ) additionalFieldsToSet.each{ |fieldName,fieldValue| addFieldValuePair( fieldName, nil, nil, fieldValue ) } end return addRecord( dbid, @fvlist ) end nil end
API_UserRoles
# File lib/QuickBaseClient.rb, line 3059 def userRoles( dbid ) @dbid = dbid sendRequest( :userRoles ) @users = getResponseElement( :users ) return self if @chainAPIcalls if block_given? if @users user_list = getResponseElements("qdbapi/users/user") user_list.each{|user| yield user} else yield nil end else @users end end
Given an array of field names or field IDs and a table ID, builds an array of valid field IDs and field names. Throws an exception when an invalid name or ID is encountered.
# File lib/QuickBaseClient.rb, line 1193 def verifyFieldList( fnames, fids = nil, dbid = @dbid ) getSchema( dbid ) @fids = @fnames = nil if fids if fids.is_a?( Array ) and fids.length > 0 fids.each { |id| fid = lookupField( id ) if fid fname = lookupFieldNameFromID( id ) @fnames ||= [] @fnames << fname else raise "verifyFieldList: '#{id}' is not a valid field ID" end } @fids = fids else raise "verifyFieldList: fids must be an array of one or more field IDs" end elsif fnames if fnames.is_a?( Array ) and fnames.length > 0 fnames.each { |name| fid = lookupFieldIDByName( name ) if fid @fids ||= [] @fids << fid else raise "verifyFieldList: '#{name}' is not a valid field name" end } @fnames = fnames else raise "verifyFieldList: fnames must be an array of one or more field names" end else raise "verifyFieldList: must specify fids or fnames" end @fids end
Returns a valid query operator.
# File lib/QuickBaseClient.rb, line 1302 def verifyQueryOperator( operator, fieldType ) queryOperator = "" if @queryOperators.nil? @queryOperators = {} @queryOperatorFieldType = {} @queryOperators[ "CT" ] = [ "contains", "[]" ] @queryOperators[ "XCT" ] = [ "does not contain", "![]" ] @queryOperators[ "EX" ] = [ "is", "==", "eq" ] @queryOperators[ "TV" ] = [ "true value" ] @queryOperators[ "XEX" ] = [ "is not", "!=", "ne" ] @queryOperators[ "SW" ] = [ "starts with" ] @queryOperators[ "XSW" ] = [ "does not start with" ] @queryOperators[ "BF" ] = [ "is before", "<" ] @queryOperators[ "OBF" ] = [ "is on or before", "<=" ] @queryOperators[ "AF" ] = [ "is after", ">" ] @queryOperators[ "OAF" ] = [ "is on or after", ">=" ] @queryOperatorFieldType[ "BF" ] = [ "date" ] @queryOperatorFieldType[ "OBF" ] = [ "date" ] @queryOperatorFieldType[ "ABF" ] = [ "date" ] @queryOperatorFieldType[ "OAF" ] = [ "date" ] @queryOperators[ "LT" ] = [ "is less than", "<" ] @queryOperators[ "LTE" ] = [ "is less than or equal to", "<=" ] @queryOperators[ "GT" ] = [ "is greater than", ">" ] @queryOperators[ "GTE" ] = [ "is greater than or equal to", ">=" ] end upcaseOperator = operator.upcase @queryOperators.each { |queryop,aliases| if queryop == upcaseOperator if @queryOperatorFieldType[ queryop ] and @queryOperatorFieldType[ queryop ].include?( fieldType ) queryOperator = upcaseOperator break else queryOperator = upcaseOperator break end else aliases.each { |a| if a == upcaseOperator if @queryOperatorFieldType[ queryop ] and @queryOperatorFieldType[ queryop ].include?( fieldType ) queryOperator = queryop break else queryOperator = queryop break end end } end } queryOperator end
Private Instance Methods
Called by client methods to notify event subscribers
# File lib/QuickBaseClient.rb, line 1587 def fire( event ) if @eventSubscribers and @eventSubscribers.include?( event ) handlers = @eventSubscribers[ event ] if handlers handlers.each{ |handler| handler.handle( event ) } end end end
Called when a response is returned from QuickBase
. Subscribers listening for onSetActiveTable, onSetActiveRecord, onSetActiveField events will be notified if the ‘active’ table, record, or field changes.
# File lib/QuickBaseClient.rb, line 1545 def fireDBChangeEvents() if @dbid and @prev_dbid != @dbid resetrid resetfid fire( "onSetActiveTable" ) end @prev_dbid = @dbid if @rid and @prev_rid != @rid resetfid fire( "onSetActiveRecord" ) end @prev_rid = @rid if @fid and @prev_fid != @fid fire( "onSetActiveField" ) end @prev_fid = @fid end