quickbase_client 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. data/README.rdoc +2 -0
  2. data/lib/QuickBaseClient.rb +145 -91
  3. metadata +3 -3
data/README.rdoc CHANGED
@@ -29,6 +29,8 @@ More information about the QuickBase Client is available here -
29
29
 
30
30
  == Change History
31
31
 
32
+ 1.0.3 - 12/07/2010 - Various small method improvements.
33
+
32
34
  1.0.2 - 12/05/2010 - Added removeFileAttachment().
33
35
 
34
36
  1.0.1 - 11/26/2010 - Will now use HTTPClient instead of Net::HTTP, if you already have HTTPClient.
@@ -13,10 +13,16 @@
13
13
 
14
14
  require 'rexml/document'
15
15
  require 'net/https'
16
- require 'socket'
17
16
  require 'json'
18
17
  require 'QuickBaseMisc'
19
18
 
19
+ begin
20
+ require 'httpclient'
21
+ USING_HTTPCLIENT = true
22
+ rescue LoadError
23
+ USING_HTTPCLIENT = false
24
+ end
25
+
20
26
  module QuickBase
21
27
 
22
28
  # QuickBase client: Version 1.0.0: Ruby wrapper class for QuickBase HTTP API.
@@ -144,25 +150,36 @@ class Client
144
150
 
145
151
  # Initializes the connection to QuickBase.
146
152
  def setHTTPConnection( useSSL, org = "www", domain = "quickbase", proxy_options = nil )
153
+ @useSSL = useSSL
147
154
  @org = org
148
155
  @domain = domain
149
- if proxy_options
150
- @httpProxy = Net::HTTP::Proxy(proxy_options["proxy_server"], proxy_options["proxy_port"], proxy_options["proxy_user"], proxy_options["proxy_password"])
151
- @httpConnection = @httpProxy.new( "#{@org}.#{@domain}.com", useSSL ? 443 : 80)
152
- else
153
- @httpConnection = Net::HTTP.new( "#{@org}.#{@domain}.com", useSSL ? 443 : 80 )
154
- end
155
- @httpConnection.use_ssl = useSSL
156
- @httpConnection.verify_mode = OpenSSL::SSL::VERIFY_NONE
156
+ if USING_HTTPCLIENT
157
+ if proxy_options
158
+ @httpConnection = HTTPClient.new( "#{proxy_options["proxy_server"]}:#{proxy_options["proxy_port"] || useSSL ? "443" : "80"}" )
159
+ @httpConnection.set_auth(proxy_options["proxy_server"], proxy_options["proxy_user"], proxy_options["proxy_password"])
160
+ else
161
+ @httpConnection = HTTPClient.new
162
+ end
163
+ else
164
+ if proxy_options
165
+ @httpProxy = Net::HTTP::Proxy(proxy_options["proxy_server"], proxy_options["proxy_port"], proxy_options["proxy_user"], proxy_options["proxy_password"])
166
+ @httpConnection = @httpProxy.new( "#{@org}.#{@domain}.com", useSSL ? 443 : 80)
167
+ else
168
+ @httpConnection = Net::HTTP.new( "#{@org}.#{@domain}.com", useSSL ? 443 : 80 )
169
+ end
170
+ @httpConnection.use_ssl = useSSL
171
+ @httpConnection.verify_mode = OpenSSL::SSL::VERIFY_NONE
172
+ end
157
173
  end
158
174
 
159
175
  # Causes useful information to be printed to the screen for every HTTP request.
160
176
  def debugHTTPConnection()
161
- @httpConnection.set_debug_output $stdout if @httpConnection
177
+ @httpConnection.set_debug_output $stdout if @httpConnection and USING_HTTPCLIENT == false
162
178
  end
163
179
 
164
180
  # Sets the QuickBase URL and port to use for requests.
165
181
  def setqbhost( useSSL, org = "www", domain = "quickbase" )
182
+ @useSSL = useSSL
166
183
  @org = org
167
184
  @domain = domain
168
185
  @qbhost = useSSL ? "https://#{@org}.#{@domain}.com:443" : "http://#{@org}.#{@domain}.com"
@@ -216,8 +233,14 @@ class Client
216
233
  begin
217
234
 
218
235
  # send the request
219
- @responseCode, @responseXML = @httpConnection.post( @requestURL, @requestXML, @requestHeaders )
220
-
236
+ if USING_HTTPCLIENT
237
+ response = @httpConnection.post( @requestURL, @requestXML, @requestHeaders )
238
+ @responseCode = response.status
239
+ @responseXML = response.content
240
+ else
241
+ @responseCode, @responseXML = @httpConnection.post( @requestURL, @requestXML, @requestHeaders )
242
+ end
243
+
221
244
  printResponse( @responseCode, @responseXML ) if @printRequestsAndResponses
222
245
 
223
246
  if not isHTMLRequest
@@ -352,7 +375,7 @@ class Client
352
375
  fire( "onProcessResponse" )
353
376
 
354
377
  parseResponseXML( responseXML )
355
- @ticket = getResponseValue( :ticket ) if @ticket.nil?
378
+ @ticket ||= getResponseValue( :ticket )
356
379
  @udata = getResponseValue( :udata )
357
380
  getErrorInfoFromResponse
358
381
  end
@@ -388,6 +411,7 @@ class Client
388
411
  # Gets the value for a specific field at the top level
389
412
  # of the XML returned from QuickBase.
390
413
  def getResponseValue( field )
414
+ @fieldValue = nil
391
415
  if field and @responseXMLdoc
392
416
  @fieldValue = @responseXMLdoc.root.elements[ field.to_s ]
393
417
  @fieldValue = fieldValue.text if fieldValue and fieldValue.has_text?
@@ -490,13 +514,14 @@ class Client
490
514
 
491
515
  # Returns the value of a field property, or nil.
492
516
  def lookupFieldPropertyByName( fieldName, property )
517
+ theproperty = nil
493
518
  if isValidFieldProperty?(property)
494
519
  fid = lookupFieldIDByName( fieldName )
495
520
  field = lookupField( fid ) if fid
496
- theproperty = nil
497
521
  theproperty = field.elements[ property ] if field
498
522
  theproperty = theproperty.text if theproperty and theproperty.has_text?
499
523
  end
524
+ theproperty
500
525
  end
501
526
 
502
527
  # Returns whether a field will show a Total on reports.
@@ -691,7 +716,7 @@ class Client
691
716
 
692
717
  # Returns an array of XML sub-elements with the specified attribute value.
693
718
  def findElementsByAttributeValue( elements, attribute_name, attribute_value )
694
- elementArray = Array.new
719
+ elementArray = []
695
720
  if elements
696
721
  if elements.is_a?( REXML::Element )
697
722
  elements.each_element_with_attribute( attribute_name, attribute_value ) { |e| elementArray << e }
@@ -708,7 +733,7 @@ class Client
708
733
 
709
734
  # Returns an array of XML sub-elements with the specified attribute name.
710
735
  def findElementsByAttributeName( elements, attribute_name )
711
- elementArray = Array.new
736
+ elementArray = []
712
737
  if elements
713
738
  elements.each_element_with_attribute( attribute_name ) { |e| elementArray << e }
714
739
  end
@@ -955,7 +980,7 @@ class Client
955
980
  if getSchema(dbid)
956
981
  if @chdbids
957
982
  chdbidArray = findElementsByAttributeName( @chdbids, "name" )
958
- chdbidArray.each{|chdbid| numTables += 1 }
983
+ numTables = chdbidArray.length
959
984
  end
960
985
  end
961
986
  numTables
@@ -990,11 +1015,9 @@ class Client
990
1015
 
991
1016
  # Returns whether a given string represents a valid QuickBase field type.
992
1017
  def isValidFieldType?( type )
993
- if @validFieldTypes.nil?
994
- @validFieldTypes = %w{ checkbox dblink date duration email file fkey float formula currency
1018
+ @validFieldTypes ||= %w{ checkbox dblink date duration email file fkey float formula currency
995
1019
  lookup phone percent rating recordid text timeofday timestamp url userid icalendarbutton }
996
- end
997
- ret = @validFieldTypes.include?( type )
1020
+ @validFieldTypes.include?( type )
998
1021
  end
999
1022
 
1000
1023
  # Returns a field type string given the more human-friendly label for a field type.
@@ -1109,7 +1132,7 @@ class Client
1109
1132
  # * filename: if the field is a file attachment field, the name of the file that should be displayed in QuickBase.
1110
1133
  # * 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.
1111
1134
  def addFieldValuePair( name, fid, filename, value )
1112
- @fvlist = Array.new if @fvlist.nil?
1135
+ @fvlist ||= []
1113
1136
  @fvlist << FieldValuePairXML.new( self, name, fid, filename, value ).to_s
1114
1137
  @fvlist
1115
1138
  end
@@ -1147,7 +1170,7 @@ class Client
1147
1170
  fid = lookupField( id )
1148
1171
  if fid
1149
1172
  fname = lookupFieldNameFromID( id )
1150
- @fnames = Array.new if @fnames.nil?
1173
+ @fnames ||= []
1151
1174
  @fnames << fname
1152
1175
  else
1153
1176
  raise "verifyFieldList: '#{id}' is not a valid field ID"
@@ -1162,7 +1185,7 @@ class Client
1162
1185
  fnames.each { |name|
1163
1186
  fid = lookupFieldIDByName( name )
1164
1187
  if fid
1165
- @fids = Array.new if @fids.nil?
1188
+ @fids ||= []
1166
1189
  @fids << fid
1167
1190
  else
1168
1191
  raise "verifyFieldList: '#{name}' is not a valid field name"
@@ -1230,8 +1253,8 @@ class Client
1230
1253
  queryOperator = ""
1231
1254
 
1232
1255
  if @queryOperators.nil?
1233
- @queryOperators = Hash.new
1234
- @queryOperatorFieldType = Hash.new
1256
+ @queryOperators = {}
1257
+ @queryOperatorFieldType = {}
1235
1258
 
1236
1259
  @queryOperators[ "CT" ] = [ "contains", "[]" ]
1237
1260
  @queryOperators[ "XCT" ] = [ "does not contain", "![]" ]
@@ -1288,16 +1311,20 @@ class Client
1288
1311
 
1289
1312
  # Get a field's base type using its name.
1290
1313
  def lookupBaseFieldTypeByName( fieldName )
1314
+ type = ""
1291
1315
  fid = lookupFieldIDByName( fieldName )
1292
1316
  field = lookupField( fid ) if fid
1293
1317
  type = field.attributes[ "base_type" ] if field
1318
+ type
1294
1319
  end
1295
1320
 
1296
1321
  # Get a field's type using its name.
1297
1322
  def lookupFieldTypeByName( fieldName )
1323
+ type = ""
1298
1324
  fid = lookupFieldIDByName( fieldName )
1299
1325
  field = lookupField( fid ) if fid
1300
1326
  type = field.attributes[ "field_type" ] if field
1327
+ type
1301
1328
  end
1302
1329
 
1303
1330
  # Returns the string required for emebedding CSV data in a request.
@@ -1438,7 +1465,7 @@ class Client
1438
1465
  # Converts a string into an array, given a field separator.
1439
1466
  # '"' followed by the field separator are treated the same way as just the field separator.
1440
1467
  def splitString( string, fieldSeparator = "," )
1441
- ra = Array.new
1468
+ ra = []
1442
1469
  string.chomp!
1443
1470
  if string.include?( "\"" )
1444
1471
  a=string.split( "\"#{fieldSeparator}" )
@@ -1456,7 +1483,7 @@ class Client
1456
1483
  # Returns the URL-encoded version of a non-printing character.
1457
1484
  def escapeXML( char )
1458
1485
  if @xmlEscapes.nil?
1459
- @xmlEscapes = Hash.new
1486
+ @xmlEscapes = {}
1460
1487
  (0..255).each{ |i| @xmlEscapes[ i.chr ] = sprintf( "&#%03d;", i ) }
1461
1488
  end
1462
1489
  return @xmlEscapes[ char ] if @xmlEscapes[ char ]
@@ -1556,10 +1583,10 @@ class Client
1556
1583
  if @events.include?( event )
1557
1584
  if handler and handler.is_a?( EventHandler )
1558
1585
  if @eventSubscribers.nil?
1559
- @eventSubscribers = Hash.new
1586
+ @eventSubscribers = {}
1560
1587
  end
1561
1588
  if not @eventSubscribers.include?( event )
1562
- @eventSubscribers[ event ] = Array.new
1589
+ @eventSubscribers[ event ] = []
1563
1590
  end
1564
1591
  if not @eventSubscribers[ event ].include?( handler )
1565
1592
  @eventSubscribers[ event ] << handler
@@ -1741,7 +1768,7 @@ class Client
1741
1768
  # API_DeleteAppZip
1742
1769
  def deleteAppZip( dbid )
1743
1770
  @dbid = dbid
1744
- sendRequest( :deleteAppZip, xmlRequestData )
1771
+ sendRequest( :deleteAppZip )
1745
1772
  return self if @chainAPIcalls
1746
1773
  @responseCode
1747
1774
  end
@@ -1864,7 +1891,7 @@ class Client
1864
1891
  # API_ChangeRecordOwner
1865
1892
  def _changeRecordOwner( rid, newowner ) changeRecordOwner( @dbid, rid, newowner ) end
1866
1893
 
1867
- # API_ChangeUserRole, using the active table id.
1894
+ # API_ChangeUserRole.
1868
1895
  def changeUserRole( dbid, userid, roleid, newroleid )
1869
1896
  @dbid, @userid, @roleid, @newroleid = dbid, userid, roleid, newroleid
1870
1897
 
@@ -2027,8 +2054,12 @@ class Client
2027
2054
 
2028
2055
  return self if @chainAPIcalls
2029
2056
 
2030
- if @records and block_given?
2031
- @records.each { |element| yield element }
2057
+ if block_given?
2058
+ if @records
2059
+ @records.each { |element| yield element }
2060
+ else
2061
+ yield nil
2062
+ end
2032
2063
  else
2033
2064
  @records
2034
2065
  end
@@ -2071,7 +2102,7 @@ class Client
2071
2102
  @numMatches
2072
2103
  end
2073
2104
 
2074
- # API_DoQuery, using the active table id.
2105
+ # API_DoQueryCount, using the active table id.
2075
2106
  def _doQueryCount( query ) doQueryCount( @dbid, query ) end
2076
2107
 
2077
2108
  # Download a file's contents from a file attachment field in QuickBase.
@@ -2082,7 +2113,7 @@ class Client
2082
2113
 
2083
2114
  @downLoadFileURL = "http://#{@org}.#{@domain}.com/up/#{dbid}/a/r#{rid}/e#{fid}/v#{vid}"
2084
2115
 
2085
- if @httpConnection.use_ssl?
2116
+ if @useSSL
2086
2117
  @downLoadFileURL.gsub!( "http:", "https:" )
2087
2118
  end
2088
2119
 
@@ -2097,8 +2128,14 @@ class Client
2097
2128
 
2098
2129
  begin
2099
2130
 
2100
- @responseCode, @fileContents = @httpConnection.get( @downLoadFileURL, @requestHeaders )
2101
-
2131
+ if USING_HTTPCLIENT
2132
+ response = @httpConnection.get( @downLoadFileURL, nil, @requestHeaders )
2133
+ @responseCode = response.status
2134
+ @fileContents = response.body.content if response.body
2135
+ else
2136
+ @responseCode, @fileContents = @httpConnection.get( @downLoadFileURL, @requestHeaders )
2137
+ end
2138
+
2102
2139
  rescue Net::HTTPBadResponse => @lastError
2103
2140
  rescue Net::HTTPHeaderSyntaxError => @lastError
2104
2141
  rescue StandardError => @lastError
@@ -2362,6 +2399,7 @@ class Client
2362
2399
 
2363
2400
  @dbid, @pageid, @pagename = dbid, pageid, pagename
2364
2401
 
2402
+ xmlRequestData = nil
2365
2403
  if @pageid
2366
2404
  xmlRequestData = toXML( :pageid, @pageid )
2367
2405
  elsif @pagename
@@ -2683,7 +2721,7 @@ class Client
2683
2721
  def importFromCSV( dbid, records_csv, clist, skipfirst = nil, msInUTC = nil )
2684
2722
 
2685
2723
  @dbid, @records_csv, @clist, @skipfirst, @msInUTC = dbid, records_csv, clist, skipfirst, msInUTC
2686
- @clist = @clist ? @clist : "0"
2724
+ @clist ||= "0"
2687
2725
 
2688
2726
  xmlRequestData = toXML( :records_csv, @records_csv )
2689
2727
  xmlRequestData << toXML( :clist, @clist )
@@ -2726,8 +2764,12 @@ class Client
2726
2764
 
2727
2765
  @pages = getResponseValue( :pages )
2728
2766
  return self if @chainAPIcalls
2729
- if @pages and block_given?
2730
- @pages.each{ |element| yield element }
2767
+ if block_given?
2768
+ if @pages
2769
+ @pages.each{ |element| yield element }
2770
+ else
2771
+ yield nil
2772
+ end
2731
2773
  else
2732
2774
  @pages
2733
2775
  end
@@ -2841,7 +2883,7 @@ class Client
2841
2883
  sendRequest( :setAppData )
2842
2884
 
2843
2885
  return self if @chainAPIcalls
2844
- return @appdata
2886
+ @appdata
2845
2887
  end
2846
2888
 
2847
2889
  # API_SetAppData, using the active table id.
@@ -3196,10 +3238,10 @@ class Client
3196
3238
 
3197
3239
  getSchema(dbid)
3198
3240
 
3199
- values = Hash.new
3200
- fieldIDs = Hash.new
3241
+ values = {}
3242
+ fieldIDs = {}
3201
3243
  if fieldNames and fieldNames.is_a?( String )
3202
- values[ fieldNames ] = Array.new
3244
+ values[ fieldNames ] = []
3203
3245
  fieldID = lookupFieldIDByName( fieldNames )
3204
3246
  if fieldID
3205
3247
  fieldIDs[ fieldNames ] = fieldID
@@ -3209,7 +3251,7 @@ class Client
3209
3251
  elsif fieldNames and fieldNames.is_a?( Array )
3210
3252
  fieldNames.each{ |name|
3211
3253
  if name
3212
- values[ name ] = Array.new
3254
+ values[ name ] = []
3213
3255
  fieldID = lookupFieldIDByName( name )
3214
3256
  if fieldID
3215
3257
  fieldIDs[ fieldID ] = name
@@ -3220,7 +3262,7 @@ class Client
3220
3262
  }
3221
3263
  elsif fieldNames.nil?
3222
3264
  getFieldNames(dbid).each{|name|
3223
- values[ name ] = Array.new
3265
+ values[ name ] = []
3224
3266
  fieldID = lookupFieldIDByName( name )
3225
3267
  fieldIDs[ fieldID ] = name
3226
3268
  }
@@ -3341,7 +3383,7 @@ class Client
3341
3383
  numRecords = 0
3342
3384
  numRecords = queryResults[fieldNames[0]].length if queryResults[fieldNames[0]]
3343
3385
  (0..(numRecords-1)).each{|recNum|
3344
- recordHash = Hash.new
3386
+ recordHash = {}
3345
3387
  fieldNames.each{|fieldName|
3346
3388
  recordHash[fieldName]=queryResults[fieldName][recNum]
3347
3389
  }
@@ -3356,8 +3398,8 @@ class Client
3356
3398
  # Same as iterateRecords but with fields optionally filtered by Ruby regular expressions.
3357
3399
  # e.g. iterateFilteredRecords( "dhnju5y7", [{"Name" => "[A-E].+}","Address"] ) { |values| puts values["Name"], values["Address"] }
3358
3400
  def iterateFilteredRecords( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil )
3359
- fields = Array.new
3360
- regexp = Hash.new
3401
+ fields = []
3402
+ regexp = {}
3361
3403
  fieldNames.each{|field|
3362
3404
  if field.is_a?(Hash)
3363
3405
  fields << field.keys[0]
@@ -3403,10 +3445,10 @@ class Client
3403
3445
  if tablesAndFields and tablesAndFields.is_a?(Array)
3404
3446
 
3405
3447
  # get all the records from QuickBase that we might need - fewer API calls is faster than processing extra data
3406
- tables = Array.new
3407
- numRecords = Hash.new
3408
- tableRecords = Hash.new
3409
- joinfield = Hash.new
3448
+ tables = []
3449
+ numRecords = {}
3450
+ tableRecords = {}
3451
+ joinfield = {}
3410
3452
 
3411
3453
  tablesAndFields.each{|tableAndFields|
3412
3454
  if tableAndFields and tableAndFields.is_a?(Hash)
@@ -3445,10 +3487,10 @@ class Client
3445
3487
  joinfieldValue = tableRecords[tables[0]][joinfield[tables[0]]][i]
3446
3488
 
3447
3489
  # save the other tables' record indices of records containing the joinfield value
3448
- tableIndices = Array.new
3490
+ tableIndices = []
3449
3491
 
3450
3492
  (1..(numTables-1)).each{|tableNum|
3451
- tableIndices[tableNum] = Array.new
3493
+ tableIndices[tableNum] = []
3452
3494
  (0..(numRecords[tables[tableNum]]-1)).each{|j|
3453
3495
  if joinfieldValue == tableRecords[tables[tableNum]][joinfield[tables[tableNum]]][j]
3454
3496
  tableIndices[tableNum] << j
@@ -3464,14 +3506,14 @@ class Client
3464
3506
 
3465
3507
  if buildJoinRecord
3466
3508
 
3467
- joinRecord = Hash.new
3509
+ joinRecord = {}
3468
3510
 
3469
3511
  tableRecords[tables[0]].each_key{|field|
3470
3512
  joinRecord[field] = tableRecords[tables[0]][field][i]
3471
3513
  }
3472
3514
 
3473
3515
  # nested loops for however many tables we have
3474
- currentIndex = Array.new
3516
+ currentIndex = []
3475
3517
  numTables.times{ currentIndex << 0 }
3476
3518
  loop {
3477
3519
  (1..(numTables-1)).each{|tableNum|
@@ -3521,7 +3563,7 @@ class Client
3521
3563
 
3522
3564
  if tables and tables.is_a?(Array)
3523
3565
  if fieldNames and fieldNames.is_a?(Array)
3524
- tableRecords = Array.new
3566
+ tableRecords = []
3525
3567
  tables.each{|table|
3526
3568
  if table and table.is_a?(Hash) and table["dbid"]
3527
3569
  tableRecords << getAllValuesForFields( table["dbid"],
@@ -3543,13 +3585,13 @@ class Client
3543
3585
  else
3544
3586
  raise "'tables' must be an Array of Hashes."
3545
3587
  end
3546
- usedRecords = Hash.new
3588
+ usedRecords = {}
3547
3589
  tableRecords.each{|queryResults|
3548
3590
  if queryResults
3549
3591
  numRecords = 0
3550
3592
  numRecords = queryResults[fieldNames[0]].length if queryResults[fieldNames[0]]
3551
3593
  (0..(numRecords-1)).each{|recNum|
3552
- recordHash = Hash.new
3594
+ recordHash = {}
3553
3595
  fieldNames.each{|fieldName|
3554
3596
  recordHash[fieldName]=queryResults[fieldName][recNum]
3555
3597
  }
@@ -3587,11 +3629,11 @@ class Client
3587
3629
  getSchema(dbid)
3588
3630
 
3589
3631
  slist = ""
3590
- summaryRecord = Hash.new
3591
- doesTotal = Hash.new
3592
- doesAverage = Hash.new
3593
- summaryField = Hash.new
3594
- fieldType = Hash.new
3632
+ summaryRecord = {}
3633
+ doesTotal = {}
3634
+ doesAverage = {}
3635
+ summaryField = {}
3636
+ fieldType = {}
3595
3637
 
3596
3638
  fieldNames.each{ |fieldName|
3597
3639
  fieldType[fieldName] = lookupFieldTypeByName(fieldName)
@@ -3642,7 +3684,7 @@ class Client
3642
3684
  yield summaryRecord
3643
3685
 
3644
3686
  count=0
3645
- summaryRecord = Hash.new
3687
+ summaryRecord = {}
3646
3688
  fieldNames.each{|fieldName|
3647
3689
  if doesTotal[fieldName]
3648
3690
  summaryRecord["#{fieldName}:Total"] = 0
@@ -3813,7 +3855,7 @@ class Client
3813
3855
  # Find the lowest value for one or more fields in the records returned by a query.
3814
3856
  # e.g. minimumsHash = min("dfdfafff",["Date Sent","Quantity","Part Name"])
3815
3857
  def min( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil )
3816
- min = Hash.new
3858
+ min = {}
3817
3859
  hasValues = false
3818
3860
  iterateRecords(dbid,fieldNames,query,qid,qname,clist,slist,fmt,options){|record|
3819
3861
  fieldNames.each{|field|
@@ -3840,7 +3882,7 @@ class Client
3840
3882
  # Find the highest value for one or more fields in the records returned by a query.
3841
3883
  # e.g. maximumsHash = max("dfdfafff",["Date Sent","Quantity","Part Name"])
3842
3884
  def max( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil )
3843
- max = Hash.new
3885
+ max = {}
3844
3886
  hasValues = false
3845
3887
  iterateRecords(dbid,fieldNames,query,qid,qname,clist,slist,fmt,options){|record|
3846
3888
  fieldNames.each{|field|
@@ -3867,7 +3909,7 @@ class Client
3867
3909
  # Returns the number non-null values for one or more fields in the records returned by a query.
3868
3910
  # e.g. countsHash = count("dfdfafff",["Date Sent","Quantity","Part Name"])
3869
3911
  def count( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil )
3870
- count = Hash.new
3912
+ count = {}
3871
3913
  fieldNames.each{|field| count[field]=0 }
3872
3914
  hasValues = false
3873
3915
  iterateRecords(dbid,fieldNames,query,qid,qname,clist,slist,fmt,options){|record|
@@ -3885,7 +3927,7 @@ class Client
3885
3927
  # Returns the sum of the values for one or more fields in the records returned by a query.
3886
3928
  # e.g. sumsHash = sum("dfdfafff",["Date Sent","Quantity","Part Name"])
3887
3929
  def sum( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil )
3888
- sum = Hash.new
3930
+ sum = {}
3889
3931
  hasValues = false
3890
3932
  iterateRecords(dbid,fieldNames,query,qid,qname,clist,slist,fmt,options){|record|
3891
3933
  fieldNames.each{|field|
@@ -3914,9 +3956,9 @@ class Client
3914
3956
  # Returns the average of the values for one or more fields in the records returned by a query.
3915
3957
  # e.g. averagesHash = average("dfdfafff",["Date Sent","Quantity","Part Name"])
3916
3958
  def average( dbid, fieldNames, query = nil, qid = nil, qname = nil, clist = nil, slist = nil, fmt = "structured", options = nil )
3917
- count = Hash.new
3959
+ count = {}
3918
3960
  fieldNames.each{|field| count[field]=0 }
3919
- sum = Hash.new
3961
+ sum = {}
3920
3962
  iterateRecords(dbid,fieldNames,query,qid,qname,clist,slist,fmt,options){|record|
3921
3963
  fieldNames.each{|field|
3922
3964
  value = record[field]
@@ -3937,7 +3979,7 @@ class Client
3937
3979
  end
3938
3980
  }
3939
3981
  }
3940
- average = Hash.new
3982
+ average = {}
3941
3983
  hasValues = false
3942
3984
  fieldNames.each{|field|
3943
3985
  if sum[field] and count[field] > 0
@@ -4009,7 +4051,7 @@ class Client
4009
4051
  end
4010
4052
  field = lookupField( fid )
4011
4053
  if field
4012
- choices = Array.new
4054
+ choices = []
4013
4055
  choicesProc = proc { |element|
4014
4056
  if element.is_a?(REXML::Element)
4015
4057
  if element.name == "choice" and element.has_text?
@@ -4028,7 +4070,7 @@ class Client
4028
4070
  # Get an array of all the record IDs for a specified table.
4029
4071
  # e.g. IDs = getAllRecordIDs( "dhnju5y7" ){ |id| puts "Record #{id}" }
4030
4072
  def getAllRecordIDs( dbid )
4031
- rids = Array.new
4073
+ rids = []
4032
4074
  if dbid
4033
4075
  getSchema( dbid )
4034
4076
  next_record_id = getResponseElement( "table/original/next_record_id" )
@@ -4055,7 +4097,7 @@ class Client
4055
4097
  # Returns a hash with the structure { "duplicated values" => [ rid, rid, ... ] }
4056
4098
  def findDuplicateRecordIDs( fnames, fids, dbid = @dbid, ignoreCase = true )
4057
4099
  verifyFieldList( fnames, fids, dbid )
4058
- duplicates = Hash.new
4100
+ duplicates = {}
4059
4101
  if @fids
4060
4102
  cslist = @fids.join( "." )
4061
4103
  ridFields = lookupFieldsByType( "recordid" )
@@ -4063,11 +4105,11 @@ class Client
4063
4105
  cslist << "."
4064
4106
  recordidFid = ridFields.last.attributes["id"]
4065
4107
  cslist << recordidFid
4066
- valuesUsed = Hash.new
4108
+ valuesUsed = {}
4067
4109
  doQuery( @dbid, nil, nil, nil, cslist ) { |record|
4068
4110
  next unless record.is_a?( REXML::Element) and record.name == "record"
4069
4111
  recordID = ""
4070
- recordValues = Array.new
4112
+ recordValues = []
4071
4113
  record.each { |f|
4072
4114
  if f.is_a?( REXML::Element) and f.name == "f" and f.has_text?
4073
4115
  if recordidFid == f.attributes["id"]
@@ -4078,7 +4120,7 @@ class Client
4078
4120
  end
4079
4121
  }
4080
4122
  if not valuesUsed[ recordValues ]
4081
- valuesUsed[ recordValues ] = Array.new
4123
+ valuesUsed[ recordValues ] = []
4082
4124
  end
4083
4125
  valuesUsed[ recordValues ] << recordID
4084
4126
  }
@@ -4108,7 +4150,7 @@ class Client
4108
4150
  if options and not options.is_a?( Hash )
4109
4151
  raise "deleteDuplicateRecords: 'options' parameter must be a Hash"
4110
4152
  else
4111
- options = Hash.new
4153
+ options = {}
4112
4154
  options[ "keeplastrecord" ] = true
4113
4155
  options[ "ignoreCase" ] = true
4114
4156
  end
@@ -4132,7 +4174,7 @@ class Client
4132
4174
  end
4133
4175
  end
4134
4176
  }
4135
- newRecordIDs = Array.new
4177
+ newRecordIDs = []
4136
4178
  if @fvlist and @fvlist.length > 0
4137
4179
  numCopies.times {
4138
4180
  addRecord( dbid, @fvlist )
@@ -4186,7 +4228,7 @@ class Client
4186
4228
  excel.Quit
4187
4229
 
4188
4230
  csvData = ""
4189
- targetFieldIDs = Array.new
4231
+ targetFieldIDs = []
4190
4232
 
4191
4233
  if fieldNames and fieldNames.length > 0
4192
4234
  fieldNames.each{ |fieldNameRow|
@@ -4261,7 +4303,7 @@ class Client
4261
4303
  if dbid
4262
4304
  getSchema( dbid )
4263
4305
 
4264
- targetFieldIDs = Array.new
4306
+ targetFieldIDs = []
4265
4307
 
4266
4308
  if targetFieldNames and targetFieldNames.is_a?( Array )
4267
4309
  targetFieldNames.each{ |fieldName|
@@ -4271,8 +4313,8 @@ class Client
4271
4313
  end
4272
4314
 
4273
4315
  useAddRecord = false
4274
- invalidLines = Array.new
4275
- validLines = Array.new
4316
+ invalidLines = []
4317
+ validLines = []
4276
4318
 
4277
4319
  linenum = 1
4278
4320
  IO.foreach( filename ){ |line|
@@ -4437,6 +4479,18 @@ class Client
4437
4479
  def _updateFile( filename, fileAttachmentFieldName )
4438
4480
  updateFile( @dbid, @rid, filename, fileAttachmentFieldName )
4439
4481
  end
4482
+
4483
+ # Remove the file from a File Attachment field in an existing record.
4484
+ # e.g. removeFileAttachment( "bdxxxibz4", "6", "Document" )
4485
+ def removeFileAttachment( dbid, rid , fileAttachmentFieldName )
4486
+ updateFile( dbid, rid, "delete", fileAttachmentFieldName )
4487
+ end
4488
+
4489
+ # Remove the file from a File Attachment field in an existing record in the active table
4490
+ # e.g. _removeFileAttachment( "6", "Document" )
4491
+ def _removeFileAttachment( rid , fileAttachmentFieldName )
4492
+ updateFile( @dbid, rid, "delete", fileAttachmentFieldName )
4493
+ end
4440
4494
 
4441
4495
  # Translate a simple SQL SELECT statement to a QuickBase query and run it.
4442
4496
  #
@@ -4457,14 +4511,14 @@ class Client
4457
4511
  slist = nil
4458
4512
  state = nil
4459
4513
  dbname = ""
4460
- columns = Array.new
4461
- sortFields = Array.new
4514
+ columns = []
4515
+ sortFields = []
4462
4516
  limit = nil
4463
4517
  offset = nil
4464
4518
  options = nil
4465
4519
  getRecordCount = false
4466
4520
 
4467
- queryFields = Array.new
4521
+ queryFields = []
4468
4522
  query = "{'["
4469
4523
  queryState = "getFieldName"
4470
4524
  queryField = ""
@@ -4774,7 +4828,7 @@ class Client
4774
4828
 
4775
4829
  end
4776
4830
 
4777
- # Iterate @records XML and yield only <record> elements.
4831
+ # Iterate @records XML and yield only 'record' elements.
4778
4832
  def eachRecord( records = @records )
4779
4833
  if records and block_given?
4780
4834
  records.each { |record|
@@ -4787,7 +4841,7 @@ class Client
4787
4841
  nil
4788
4842
  end
4789
4843
 
4790
- # Iterate record XML and yield only <f> elements.
4844
+ # Iterate record XML and yield only 'f' elements.
4791
4845
  def eachField( record = @record )
4792
4846
  if record and block_given?
4793
4847
  record.each{ |field|
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 1
7
7
  - 0
8
- - 2
9
- version: 1.0.2
8
+ - 3
9
+ version: 1.0.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Gareth Lewis
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-12-05 00:00:00 -08:00
17
+ date: 2010-12-07 00:00:00 -08:00
18
18
  default_executable:
19
19
  dependencies: []
20
20