ipp_quickbase_devkit 0.0.1

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 (239) hide show
  1. data/LICENSE +87 -0
  2. data/README.rdoc +112 -0
  3. data/doc/QuickBaseClient.rb.htm +1896 -0
  4. data/doc/ReleaseNotes.txt +43 -0
  5. data/doc/qbc.makeCSVFile.qbc +4 -0
  6. data/doc/qbc.makeCSVFile.rb +4 -0
  7. data/doc/quickbase_adapter.rb.htm +399 -0
  8. data/examples/cookbookfiles/QuickBaseAPICookbook.html +2590 -0
  9. data/examples/cookbookfiles/addChangeRemoveUserRole.rb +21 -0
  10. data/examples/cookbookfiles/addOrEditRecord.rb +10 -0
  11. data/examples/cookbookfiles/application_object.rb +55 -0
  12. data/examples/cookbookfiles/applyRubyFormulas.rb +10 -0
  13. data/examples/cookbookfiles/average.rb +27 -0
  14. data/examples/cookbookfiles/backupApplication.rb +8 -0
  15. data/examples/cookbookfiles/cacheSchemas.rb +53 -0
  16. data/examples/cookbookfiles/calculateRunningTotals.rb +11 -0
  17. data/examples/cookbookfiles/copyrecords.rb +73 -0
  18. data/examples/cookbookfiles/count.rb +26 -0
  19. data/examples/cookbookfiles/createRecordNavigatorHTML.rb +42 -0
  20. data/examples/cookbookfiles/createReportDashboard.rb +35 -0
  21. data/examples/cookbookfiles/createTable.rb +12 -0
  22. data/examples/cookbookfiles/deviation.rb +25 -0
  23. data/examples/cookbookfiles/downloadCookbook.rb +97 -0
  24. data/examples/cookbookfiles/downloadFile.rb +10 -0
  25. data/examples/cookbookfiles/downloadFilesToFolder.rb +81 -0
  26. data/examples/cookbookfiles/downloadToTextFile.rb +64 -0
  27. data/examples/cookbookfiles/dumpSchema.rb +11 -0
  28. data/examples/cookbookfiles/duplicateRecord.rb +8 -0
  29. data/examples/cookbookfiles/dynamicMethods.rb +33 -0
  30. data/examples/cookbookfiles/editRecords.rb +15 -0
  31. data/examples/cookbookfiles/findJohnsLast10Records.rb +17 -0
  32. data/examples/cookbookfiles/findRubyRecords.rb +17 -0
  33. data/examples/cookbookfiles/formatCurrency.rb +24 -0
  34. data/examples/cookbookfiles/formatDate.rb +10 -0
  35. data/examples/cookbookfiles/formatDuration.rb +27 -0
  36. data/examples/cookbookfiles/formatPercent.rb +24 -0
  37. data/examples/cookbookfiles/getAllValuesForFields.rb +18 -0
  38. data/examples/cookbookfiles/getAppDTMInfo.rb +29 -0
  39. data/examples/cookbookfiles/getApplicationVariable.rb +5 -0
  40. data/examples/cookbookfiles/getChildTableDBID.rb +11 -0
  41. data/examples/cookbookfiles/getColumnListForReport.rb +6 -0
  42. data/examples/cookbookfiles/getFieldChoices.rb +13 -0
  43. data/examples/cookbookfiles/getFieldIDs.rb +6 -0
  44. data/examples/cookbookfiles/getFieldNames.rb +6 -0
  45. data/examples/cookbookfiles/getLastModTime.rb +8 -0
  46. data/examples/cookbookfiles/getLastRecModTime.rb +8 -0
  47. data/examples/cookbookfiles/getNumRecords.rb +8 -0
  48. data/examples/cookbookfiles/getNumTables.rb +4 -0
  49. data/examples/cookbookfiles/getRecord.rb +5 -0
  50. data/examples/cookbookfiles/getRecordDisplayURL.rb +13 -0
  51. data/examples/cookbookfiles/getRecordsAddedToday.rb +20 -0
  52. data/examples/cookbookfiles/getRecordsAsJSON.rb +6 -0
  53. data/examples/cookbookfiles/getReportNames.rb +25 -0
  54. data/examples/cookbookfiles/getRoleInfo.rb +48 -0
  55. data/examples/cookbookfiles/getServerStatus.rb +11 -0
  56. data/examples/cookbookfiles/getSortListForReport.rb +6 -0
  57. data/examples/cookbookfiles/getTableIDs.rb +6 -0
  58. data/examples/cookbookfiles/getTableName.rb +8 -0
  59. data/examples/cookbookfiles/getTableNames.rb +25 -0
  60. data/examples/cookbookfiles/getTimeCreated.rb +8 -0
  61. data/examples/cookbookfiles/getTimeInMilliseconds.rb +5 -0
  62. data/examples/cookbookfiles/getUserInfo.rb +26 -0
  63. data/examples/cookbookfiles/getUserRole.rb +15 -0
  64. data/examples/cookbookfiles/intranet.rb +101 -0
  65. data/examples/cookbookfiles/isAverageField.rb +17 -0
  66. data/examples/cookbookfiles/isDbidString.rb +8 -0
  67. data/examples/cookbookfiles/isTotalField.rb +16 -0
  68. data/examples/cookbookfiles/iterateDBPages.rb +8 -0
  69. data/examples/cookbookfiles/iterateFilteredRecords.rb +12 -0
  70. data/examples/cookbookfiles/iterateJoinRecords.rb +68 -0
  71. data/examples/cookbookfiles/iterateRecordInfos.rb +8 -0
  72. data/examples/cookbookfiles/iterateRecords.rb +23 -0
  73. data/examples/cookbookfiles/iterateSummaryRecords.rb +13 -0
  74. data/examples/cookbookfiles/iterateUnionRecords.rb +38 -0
  75. data/examples/cookbookfiles/listAccessibleApplications.rb +6 -0
  76. data/examples/cookbookfiles/logRequestAndResponseXML.rb +8 -0
  77. data/examples/cookbookfiles/lookupFieldPropertyByName.rb +62 -0
  78. data/examples/cookbookfiles/lookupFieldTypeByName.rb +10 -0
  79. data/examples/cookbookfiles/makeCSVFile.rb +4 -0
  80. data/examples/cookbookfiles/makeSlideShow.rb +42 -0
  81. data/examples/cookbookfiles/makerecs.rb +64 -0
  82. data/examples/cookbookfiles/max.rb +26 -0
  83. data/examples/cookbookfiles/min.rb +26 -0
  84. data/examples/cookbookfiles/percent.rb +29 -0
  85. data/examples/cookbookfiles/printChildElements.rb +54 -0
  86. data/examples/cookbookfiles/printNewRecords.rb +12 -0
  87. data/examples/cookbookfiles/processRESTRequest.rb +21 -0
  88. data/examples/cookbookfiles/provisionAndInviteNewUser.rb +13 -0
  89. data/examples/cookbookfiles/purgeRecords.rb +15 -0
  90. data/examples/cookbookfiles/quickbase_adapter.rb.htm +397 -0
  91. data/examples/cookbookfiles/quickbase_record_finder.zip +0 -0
  92. data/examples/cookbookfiles/recordAndFieldIterator.rb +24 -0
  93. data/examples/cookbookfiles/runImport.rb +9 -0
  94. data/examples/cookbookfiles/runQuickBaseTwitterConnector.rb +41 -0
  95. data/examples/cookbookfiles/sendToQuickBase.rb +33 -0
  96. data/examples/cookbookfiles/setDBvar.rb +6 -0
  97. data/examples/cookbookfiles/showRequestAndResponseXML.rb +8 -0
  98. data/examples/cookbookfiles/sqlQuery.rb +11 -0
  99. data/examples/cookbookfiles/stopOnError.rb +10 -0
  100. data/examples/cookbookfiles/sum.rb +26 -0
  101. data/examples/cookbookfiles/twitterFromQuickBase.rb +42 -0
  102. data/examples/cookbookfiles/twitterWithQuickBase.rb +36 -0
  103. data/examples/cookbookfiles/uploadCSVData.rb +20 -0
  104. data/examples/cookbookfiles/uploadExcelData.rb +22 -0
  105. data/examples/cookbookfiles/uploadFileEveryHour.rb +18 -0
  106. data/examples/cookbookfiles/uploadFileIntoNewRecord.rb +8 -0
  107. data/examples/cookbookfiles/uploadFilesFromFolder.exe +0 -0
  108. data/examples/cookbookfiles/uploadFilesFromFolder.rb +69 -0
  109. data/examples/cookbookfiles/useCompanyURL.rb +12 -0
  110. data/examples/cookbookfiles/userRoles.rb +49 -0
  111. data/examples/cookbookfiles/watchCommunityForum.rb +5 -0
  112. data/examples/cookbookfiles/wikifyTable.rb +29 -0
  113. data/examples/cookbookfiles/xmlShortcuts.rb +33 -0
  114. data/examples/pmp/app/controllers/application.rb +7 -0
  115. data/examples/pmp/app/controllers/contacts_controller.rb +8 -0
  116. data/examples/pmp/app/controllers/document_library_controller.rb +2 -0
  117. data/examples/pmp/app/controllers/issues_controller.rb +5 -0
  118. data/examples/pmp/app/controllers/projects_controller.rb +22 -0
  119. data/examples/pmp/app/controllers/resources_controller.rb +2 -0
  120. data/examples/pmp/app/controllers/tasks_controller.rb +13 -0
  121. data/examples/pmp/app/controllers/time_cards_controller.rb +5 -0
  122. data/examples/pmp/app/helpers/application_helper.rb +3 -0
  123. data/examples/pmp/app/helpers/contacts_helper.rb +2 -0
  124. data/examples/pmp/app/helpers/document_library_helper.rb +2 -0
  125. data/examples/pmp/app/helpers/issues_helper.rb +2 -0
  126. data/examples/pmp/app/helpers/projects_helper.rb +2 -0
  127. data/examples/pmp/app/helpers/resources_helper.rb +2 -0
  128. data/examples/pmp/app/helpers/tasks_helper.rb +2 -0
  129. data/examples/pmp/app/helpers/time_cards_helper.rb +2 -0
  130. data/examples/pmp/app/models/contacts.rb +26 -0
  131. data/examples/pmp/app/models/document_library.rb +2 -0
  132. data/examples/pmp/app/models/issues.rb +6 -0
  133. data/examples/pmp/app/models/projects.rb +26 -0
  134. data/examples/pmp/app/models/resources.rb +2 -0
  135. data/examples/pmp/app/models/tasks.rb +12 -0
  136. data/examples/pmp/app/models/time_cards.rb +7 -0
  137. data/examples/pmp/app/schemas/contacts.xml +1 -0
  138. data/examples/pmp/app/schemas/document_library.xml +1 -0
  139. data/examples/pmp/app/schemas/issues.xml +1 -0
  140. data/examples/pmp/app/schemas/pmp.xml +1 -0
  141. data/examples/pmp/app/schemas/projects.xml +1 -0
  142. data/examples/pmp/app/schemas/readme.txt +8 -0
  143. data/examples/pmp/app/schemas/resources.xml +1 -0
  144. data/examples/pmp/app/schemas/tasks.xml +1 -0
  145. data/examples/pmp/app/schemas/time_cards.xml +1 -0
  146. data/examples/pmp/app/views/contacts/companies.rhtml +31 -0
  147. data/examples/pmp/app/views/contacts/project_contacts.rhtml +31 -0
  148. data/examples/pmp/app/views/issues/filter_issues.rhtml +26 -0
  149. data/examples/pmp/app/views/layouts/application.rhtml +56 -0
  150. data/examples/pmp/app/views/projects/all_projects.rhtml +33 -0
  151. data/examples/pmp/app/views/projects/home.rhtml +11 -0
  152. data/examples/pmp/app/views/projects/my_open_projects.rhtml +27 -0
  153. data/examples/pmp/app/views/projects/open_projects.rhtml +44 -0
  154. data/examples/pmp/app/views/projects/project_sorted_by_company.rhtml +40 -0
  155. data/examples/pmp/app/views/projects/projects_sorted_by_priority.rhtml +30 -0
  156. data/examples/pmp/app/views/projects/updated_projects.rhtml +0 -0
  157. data/examples/pmp/app/views/tasks/all_tasks.rhtml +27 -0
  158. data/examples/pmp/app/views/tasks/search.rhtml +23 -0
  159. data/examples/pmp/app/views/tasks/search2.rhtml +23 -0
  160. data/examples/pmp/app/views/tasks/search3.rhtml +23 -0
  161. data/examples/pmp/app/views/time_cards/summary.rhtml +38 -0
  162. data/examples/pmp/config/boot.rb +45 -0
  163. data/examples/pmp/config/database.yml +30 -0
  164. data/examples/pmp/config/environment.rb +60 -0
  165. data/examples/pmp/config/environments/development.rb +21 -0
  166. data/examples/pmp/config/environments/production.rb +18 -0
  167. data/examples/pmp/config/environments/test.rb +19 -0
  168. data/examples/pmp/config/routes.rb +23 -0
  169. data/examples/pmp/db/migrate/001_create_projects.rb +10 -0
  170. data/examples/pmp/db/migrate/002_create_tasks.rb +10 -0
  171. data/examples/pmp/db/migrate/003_create_issues.rb +10 -0
  172. data/examples/pmp/db/migrate/004_create_document_libraries.rb +10 -0
  173. data/examples/pmp/db/migrate/005_create_resources.rb +10 -0
  174. data/examples/pmp/db/migrate/006_create_time_cards.rb +10 -0
  175. data/examples/pmp/db/migrate/007_create_contacts.rb +10 -0
  176. data/examples/pmp/public/404.html +30 -0
  177. data/examples/pmp/public/500.html +30 -0
  178. data/examples/pmp/public/app.index.html +277 -0
  179. data/examples/pmp/public/dispatch.cgi +10 -0
  180. data/examples/pmp/public/dispatch.fcgi +24 -0
  181. data/examples/pmp/public/dispatch.rb +10 -0
  182. data/examples/pmp/public/favicon.ico +0 -0
  183. data/examples/pmp/public/images/rails.png +0 -0
  184. data/examples/pmp/public/javascripts/application.js +2 -0
  185. data/examples/pmp/public/javascripts/controls.js +833 -0
  186. data/examples/pmp/public/javascripts/dragdrop.js +942 -0
  187. data/examples/pmp/public/javascripts/effects.js +1088 -0
  188. data/examples/pmp/public/javascripts/prototype.js +2515 -0
  189. data/examples/pmp/public/robots.txt +1 -0
  190. data/examples/pmp/test/fixtures/contacts.yml +5 -0
  191. data/examples/pmp/test/fixtures/document_libraries.yml +5 -0
  192. data/examples/pmp/test/fixtures/issues.yml +5 -0
  193. data/examples/pmp/test/fixtures/projects.yml +5 -0
  194. data/examples/pmp/test/fixtures/resources.yml +5 -0
  195. data/examples/pmp/test/fixtures/tasks.yml +5 -0
  196. data/examples/pmp/test/fixtures/time_cards.yml +5 -0
  197. data/examples/pmp/test/functional/contacts_controller_test.rb +18 -0
  198. data/examples/pmp/test/functional/document_library_controller_test.rb +18 -0
  199. data/examples/pmp/test/functional/issues_controller_test.rb +18 -0
  200. data/examples/pmp/test/functional/projects_controller_test.rb +18 -0
  201. data/examples/pmp/test/functional/resources_controller_test.rb +18 -0
  202. data/examples/pmp/test/functional/tasks_controller_test.rb +18 -0
  203. data/examples/pmp/test/functional/time_cards_controller_test.rb +18 -0
  204. data/examples/pmp/test/test_helper.rb +28 -0
  205. data/examples/pmp/test/unit/contacts_test.rb +10 -0
  206. data/examples/pmp/test/unit/document_library_test.rb +10 -0
  207. data/examples/pmp/test/unit/issues_test.rb +10 -0
  208. data/examples/pmp/test/unit/projects_test.rb +10 -0
  209. data/examples/pmp/test/unit/resources_test.rb +10 -0
  210. data/examples/pmp/test/unit/tasks_test.rb +10 -0
  211. data/examples/pmp/test/unit/time_cards_test.rb +10 -0
  212. data/lib/QuickBaseClient.rb +5054 -0
  213. data/lib/QuickBaseCommandLineClient.rb +401 -0
  214. data/lib/QuickBaseContactsAppBuilder.rb +419 -0
  215. data/lib/QuickBaseEmailer.rb +334 -0
  216. data/lib/QuickBaseEventNotifier.rb +592 -0
  217. data/lib/QuickBaseMisc.rb +96 -0
  218. data/lib/QuickBaseObjects.rb +566 -0
  219. data/lib/QuickBaseRSSGenerator.rb +286 -0
  220. data/lib/QuickBaseTextData.rb +545 -0
  221. data/lib/QuickBaseTwitterConnector.rb +300 -0
  222. data/lib/QuickBaseWebClient.rb +126 -0
  223. data/lib/WorkPlaceClient.rb +45 -0
  224. data/lib/qbc.makeCSVFile.qbc +4 -0
  225. data/lib/qbc.makeCSVFile.rb +17 -0
  226. data/lib/quickbase_adapter.rb +320 -0
  227. data/lib/runFieldEntryDialog.rb +151 -0
  228. data/lib/runOfflineFieldEntryDialog.rb +203 -0
  229. data/rakefile +100 -0
  230. data/test/run_tests.bat +7 -0
  231. data/test/spec_all_tests.rb +13 -0
  232. data/test/spec_smoke_tests.rb +58 -0
  233. data/test/spec_workplace_addrecord_test.rb +46 -0
  234. data/test/spec_workplace_base_test.rb +57 -0
  235. data/test/spec_workplace_editrecord_test.rb +38 -0
  236. data/test/spec_workplace_json_test.rb +38 -0
  237. data/test/spec_workplace_objects_test.rb +39 -0
  238. data/test/spec_workplace_smoke_tests.rb +45 -0
  239. metadata +353 -0
@@ -0,0 +1,4 @@
1
+ signin my_username my_password
2
+ open My QuickBase Database
3
+ exportfile MyCSVFile.csv
4
+ quit
@@ -0,0 +1,17 @@
1
+ #--#####################################################################
2
+ # Copyright (c) 2009 Gareth Lewis and Intuit, Inc.
3
+ #
4
+ # All rights reserved. This program and the accompanying materials
5
+ # are made available under the terms of the Eclipse Public License v1.0
6
+ # which accompanies this distribution, and is available at
7
+ # http://www.opensource.org/licenses/eclipse-1.0.php
8
+ #
9
+ # Contributors:
10
+ # Gareth Lewis - Initial contribution.
11
+ # Intuit Partner Platform.
12
+ #++#####################################################################
13
+
14
+ require 'QuickBaseClient'
15
+ qbc = QuickBase::Client.new( "my_username", "my_password", "My QuickBase Database" )
16
+ qbc.makeSVFile( "MyCSVFile.csv" )
17
+ qbc.signOut
@@ -0,0 +1,320 @@
1
+ #--#####################################################################
2
+ # Copyright (c) 2009 Gareth Lewis and Intuit, Inc.
3
+ #
4
+ # All rights reserved. This program and the accompanying materials
5
+ # are made available under the terms of the Eclipse Public License v1.0
6
+ # which accompanies this distribution, and is available at
7
+ # http://www.opensource.org/licenses/eclipse-1.0.php
8
+ #
9
+ # Contributors:
10
+ # Gareth Lewis - Initial contribution.
11
+ # Intuit Partner Platform.
12
+ #++#####################################################################
13
+
14
+ require 'rubygems'
15
+ require 'WorkPlaceClient'
16
+ require 'QuickBaseClient'
17
+
18
+ module ActiveRecord
19
+
20
+ # Add the QuickBase connection to ActiveRecord
21
+ class Base
22
+ def self.quickbase_connection(config)
23
+ config = config.symbolize_keys
24
+
25
+ if config.has_key?(:database)
26
+ database = config[:database]
27
+ else
28
+ raise ArgumentError, "No database specified. Missing argument: database."
29
+ end
30
+
31
+ if config[:useWorkPlace]
32
+ @qbc = QuickBase::WorkPlaceClient.new(config[:username], config[:password])
33
+ else
34
+ config = config.stringify_keys
35
+ @qbc = QuickBase::Client.init(config)
36
+ end
37
+ if @qbc.findDBByName(database)
38
+ @qbc._getSchema
39
+ elsif !@qbc.getSchema(database)
40
+ raise ArgumentError, "Database '#{database}' is not accessible."
41
+ end
42
+ if config[:printRequestsAndResponses]
43
+ @qbc.printRequestsAndResponses = config[:printRequestsAndResponses]
44
+ end
45
+ if config[:cacheSchemas]
46
+ @qbc.cacheSchemas = config[:cacheSchemas]
47
+ end
48
+ ConnectionAdapters::QuickBaseAdapter.new(@qbc,nil,config)
49
+ end
50
+ end
51
+
52
+ module ConnectionAdapters
53
+
54
+ # Rails-friendly definition of a QuickBase column
55
+ class QuickBaseColumn < Column
56
+ attr_accessor :quickBaseFieldAttributes
57
+
58
+ def initialize(fieldAttributes)
59
+ @quickBaseFieldAttributes = fieldAttributes
60
+ super(@quickBaseFieldAttributes ["columnName"],@quickBaseFieldAttributes["default_value"],fieldType())
61
+ primary = @quickBaseFieldAttributes["primary"]
62
+ @quickBaseFieldAttributes["decimalPrecision"] ||= "38"
63
+ end
64
+
65
+ def name
66
+ @name.downcase.gsub( /\W/, "_" )
67
+ end
68
+
69
+ def human_name
70
+ @quickBaseFieldAttributes["quickBaseFieldName"]
71
+ end
72
+ private
73
+
74
+ def fieldType
75
+ ret = "string"
76
+ case @quickBaseFieldAttributes["quickBaseFieldType"]
77
+ when "checkbox" then ret = "boolean"
78
+ when "currency" then ret = "decimal(#{@quickBaseFieldAttributes['decimalPrecision']},2)"
79
+ when "dblink" then ret = "string"
80
+ when "date" then ret = "date"
81
+ when "duration" then ret = "decimal(#{@quickBaseFieldAttributes['decimalPrecision']},0)"
82
+ when "email" then ret = "string"
83
+ when "file" then ret = "blob"
84
+ when "fkey" then ret = "string"
85
+ when "float"
86
+ if @quickBaseFieldAttributes["decimal_places"]
87
+ ret = "decimal(#{@quickBaseFieldAttributes['decimalPrecision']},#{@quickBaseFieldAttributes['decimal_places']})"
88
+ else
89
+ ret = "decimal(#{@quickBaseFieldAttributes['decimalPrecision']},0)"
90
+ end
91
+ when "formula" then ret = "string"
92
+ when "lookup" then ret = "string"
93
+ when "phone" then ret = "string"
94
+ when "rating"
95
+ ret = "int(1)"
96
+ when "recordid" then ret = "int"
97
+ when "text" then ret = "text"
98
+ when "timeofday" then ret = "decimal(#{@quickBaseFieldAttributes['decimalPrecision']},0)"
99
+ when "timestamp" then ret = "datetime"
100
+ when "url" then ret = "string"
101
+ when "userid" then ret = "decimal(#{@quickBaseFieldAttributes['decimalPrecision']},0)"
102
+ end
103
+ ret
104
+ end
105
+ end
106
+
107
+ # The QuickBase Adapter for Rails
108
+ class QuickBaseAdapter < AbstractAdapter
109
+
110
+ def initialize(connection, logger, connection_options=nil)
111
+ super(connection, logger)
112
+ @connection_options = connection_options
113
+ @qbc = @connection
114
+ @main_dbid = @qbc.dbid.dup
115
+ @main_dbname = @qbc.dbname.dup.downcase
116
+ @id_field_name = "Record ID#"
117
+ @id_fid = "3"
118
+ @useActiveTableColumns = false
119
+ @cachedColumns = {}
120
+ end
121
+
122
+ def adapter_name
123
+ 'QuickBase'
124
+ end
125
+
126
+ def columns(table_name, name = nil)
127
+
128
+ return [] if table_name.nil? or table_name.blank?
129
+
130
+ if @useActiveTableColumns
131
+ dbid = @qbc.dbid
132
+ @useActiveTableColumns = false
133
+ else
134
+ @qbc.getSchema(@main_dbid)
135
+ if table_name.downcase != @main_dbname or @qbc.chdbids
136
+ dbid = @qbc.lookupChdbid(table_name)
137
+ @qbc.getSchema(dbid)
138
+ end
139
+ end
140
+
141
+ if @qbc.cacheSchemas and @cachedColumns[dbid]
142
+ quickBaseColumns = @cachedColumns[dbid]
143
+ else
144
+ quickBaseColumns = []
145
+ columnNames = @qbc.getFieldNames(dbid)
146
+ key_fid = @qbc.key_fid
147
+ primary = false
148
+ columnNames.each{|columnName|
149
+
150
+ fieldAttributes = {}
151
+ quickBaseFieldId = @qbc.lookupFieldIDByName(columnName)
152
+ quickBaseFieldType = @qbc.lookupFieldTypeByName(columnName)
153
+
154
+ fieldAttributes["quickBaseFieldName"] = columnName.dup
155
+ fieldAttributes["quickBaseFieldId"] = quickBaseFieldId.dup
156
+ fieldAttributes["quickBaseFieldType"] = quickBaseFieldType.dup
157
+ fieldAttributes["default_value"] = @qbc.lookupFieldPropertyByName(columnName, "default_value" )
158
+ fieldAttributes["decimal_places"] = @qbc.lookupFieldPropertyByName(columnName, "decimal_places" )
159
+
160
+ if key_fid and key_fid == quickBaseFieldId
161
+ fieldAttributes["primary"] = true
162
+ elsif quickBaseFieldType == "recordid"
163
+ @id_field_name = columnName.dup
164
+ @id_fid = quickBaseFieldId.dup
165
+ columnName = "id"
166
+ elsif quickBaseFieldId.to_i < 6
167
+ columnName << "_id"
168
+ end
169
+ fieldAttributes["columnName"] = columnName.dup
170
+ quickBaseColumn = QuickBaseColumn.new(fieldAttributes)
171
+ quickBaseColumns << quickBaseColumn
172
+ }
173
+ if @qbc.cacheSchemas
174
+ @cachedColumns[dbid] = quickBaseColumns
175
+ end
176
+ end
177
+ quickBaseColumns
178
+ end
179
+
180
+ def quote_column_name(name)
181
+ "[#{name}]"
182
+ end
183
+
184
+ def quote(value, column = nil)
185
+ ret = value ? "'#{value}'" : ''
186
+ end
187
+
188
+ def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
189
+ sql.gsub!("NULL,","'',")
190
+ @qbc.doSQLInsert(sql)
191
+ end
192
+
193
+ def update(sql, name = nil)
194
+ selectString = sql.dup
195
+ selectString.gsub!("[id]",@id_fid)
196
+ @qbc.doSQLUpdate(selectString)
197
+ end
198
+
199
+ def delete(sql, name = nil)
200
+ selectString = sql.dup
201
+ selectString.gsub!("DELETE","SELECT [id] ")
202
+ selectString.gsub!("[id]",@id_fid)
203
+ rows = select(selectString,name)
204
+ rows.each{|row|
205
+ recordID = row["id"]
206
+ @qbc._deleteRecord(recordID) if recordID
207
+ }
208
+ end
209
+
210
+ def select(sql,name)
211
+ puts sql
212
+ sql = sql.to_s
213
+
214
+ if sql.match(/([^:]+)(:)(.+)/)
215
+ table = $1
216
+ sql = $3
217
+ elsif name
218
+ table = name.split()[0]
219
+ end
220
+
221
+ rows = nil
222
+ if sql.include?("SELECT count(*)")
223
+ rows = []
224
+ rows << {"count" => @qbc.doSQLQuery(sql).to_i }
225
+ elsif sql.include?("SELECT ")
226
+ sql.gsub!(".id",".#{@id_field_name}")
227
+ rows = @qbc.doSQLQuery(sql, :Array)
228
+ rows.each{|row| row["id"] = row[@id_field_name]} if rows
229
+ elsif sql.match(/\{[^\}]+\}/) # QuickBase query
230
+ setActiveTable(table)
231
+ rows = @qbc.getAllValuesForFieldsAsArray(@qbc.dbid,@qbc.getFieldNames,sql)
232
+ rows.each{|row| row["id"] = row[@id_field_name]} if rows
233
+ elsif sql.length > 0 # named QuickBase query
234
+ setActiveTable(table)
235
+ rows = @qbc.getAllValuesForFieldsAsArray(@qbc.dbid,nil,nil,nil,sql)
236
+ rows.each{|row| row["id"] = row[@id_field_name]} if rows
237
+ end
238
+ puts rows.inspect
239
+
240
+ rows
241
+
242
+ end
243
+
244
+ def setActiveTable(table)
245
+ if table
246
+ foundTable = false
247
+ save_dbid = @qbc.dbid.dup
248
+ @qbc.getSchema(@main_dbid)
249
+ if table.downcase != @main_dbname
250
+ if @qbc.lookupChdbid(table)
251
+ if @qbc._getSchema
252
+ foundTable = true
253
+ end
254
+ elsif @qbc.findDBByname(table)
255
+ if @qbc._getSchema
256
+ foundTable = true
257
+ end
258
+ else
259
+ if @qbc.getSchema(table)
260
+ foundTable = true
261
+ end
262
+ end
263
+ end
264
+ if foundTable
265
+ @useActiveTableColumns = true
266
+ else
267
+ @qbc.getSchema(save_dbid)
268
+ end
269
+ end
270
+ @qbc.dbid
271
+ end
272
+
273
+ def execute(sql, name = nil)
274
+ if sql and sql.is_a?(String) and sql.length > 0
275
+ @qbc.instance_eval(sql)
276
+ end
277
+ end
278
+
279
+ def supports_count_distinct?
280
+ false
281
+ end
282
+
283
+ def active?
284
+ @qbc.ticket
285
+ end
286
+
287
+ def reconnect!
288
+ @qbc.signOut
289
+ @qbc.authenticate(@qbc.username,@qbc.password)
290
+ @active = !@qbc.ticket.nil?
291
+ end
292
+
293
+ def disconnect!
294
+ @qbc.signOut
295
+ @active = @qbc.ticket
296
+ end
297
+
298
+ def create_table(name, options = {})
299
+ raise NotImplementedError, "create_table is not supported by the QuickBase adapter"
300
+ end
301
+
302
+ def add_column(table_name, column_name, type, options = {})
303
+ raise NotImplementedError, "add_column is not supported by the QuickBase adapter"
304
+ end
305
+
306
+ def remove_column(table_name, column_name)
307
+ raise NotImplementedError, "remove_column is not supported by the QuickBase adapter"
308
+ end
309
+
310
+ def add_index(table_name, column_name, options = {})
311
+ raise NotImplementedError, "indexing is not supported by the QuickBase"
312
+ end
313
+
314
+ def index_name(table_name, options) #:nodoc:
315
+ raise NotImplementedError, "indexing is not supported by the QuickBase"
316
+ end
317
+
318
+ end # class QuickBaseAdapter
319
+ end # module ConnectionAdapters
320
+ end # module ActiveRecord
@@ -0,0 +1,151 @@
1
+ #--#####################################################################
2
+ # Copyright (c) 2009 Gareth Lewis and Intuit, Inc.
3
+ #
4
+ # All rights reserved. This program and the accompanying materials
5
+ # are made available under the terms of the Eclipse Public License v1.0
6
+ # which accompanies this distribution, and is available at
7
+ # http://www.opensource.org/licenses/eclipse-1.0.php
8
+ #
9
+ # Contributors:
10
+ # Gareth Lewis - Initial contribution.
11
+ # Intuit Partner Platform.
12
+ #++#####################################################################
13
+
14
+ require 'QuickBaseClient'
15
+ require 'tk'
16
+
17
+ # Display a dialog with one text entry field, and buttons to send the text to a
18
+ # field in a new record in QuickBase, go to QuickBase, and to close the dialog.
19
+ # * 'dbid' must be a valid table id.
20
+ # * 'field' must be the name or id of a text field in the 'dbid' table.
21
+ def runFieldEntryDialog(username,password,dbid,field)
22
+ @qbc = QuickBase::Client.new(username,password)
23
+ if @qbc and @qbc.requestSucceeded
24
+ @qbc.getSchema(dbid)
25
+ if @qbc.requestSucceeded
26
+ field = field.join(' ')
27
+ field.strip!
28
+ fieldID = @qbc.lookupFieldIDByName(field)
29
+ if fieldID
30
+ fieldName = field
31
+ else
32
+ fieldName = lookupFieldNameFromID(field)
33
+ fieldID = field if fieldName
34
+ end
35
+ tableName = @qbc.getResponseElement( "table/name" ).text
36
+ if fieldID and fieldName
37
+
38
+ fieldElement = @qbc.lookupField(fieldID)
39
+ numTextLines = 1
40
+ numLinesProc = proc { |element|
41
+ if element.is_a?(REXML::Element) and element.name == "num_lines" and element.has_text?
42
+ numTextLines = element.text.to_i
43
+ end
44
+ }
45
+ @qbc.processChildElements(fieldElement, true, numLinesProc)
46
+
47
+ root = TkRoot.new{ title tableName }
48
+ frame = TkFrame.new(root){
49
+ borderwidth 4
50
+ width 60
51
+ pack "side" => "top"
52
+ }
53
+ if numTextLines == 1
54
+ labelText = "Enter '#{fieldName}' and press Enter or click 'Send to QuickBase':"
55
+ else
56
+ labelText = "Enter '#{fieldName}' and click 'Send to QuickBase':"
57
+ end
58
+ fieldLabel = TkLabel.new(frame){
59
+ text labelText
60
+ font "Arial 10 bold"
61
+ pack "side"=>"top", "expand" => true
62
+ }
63
+
64
+ entryField = nil
65
+ if numTextLines == 1
66
+ entryField = TkEntry.new(frame){
67
+ font "Arial 10 bold"
68
+ pack "fill" => "x", "expand" => true, "side" => "top", "padx" =>5, "pady"=>5
69
+ }
70
+ entryField.bind('Key-Return') {|e|
71
+ value = entryField.get
72
+ @qbc.clearFieldValuePairList
73
+ @qbc.addFieldValuePair(nil,fieldID,nil,value)
74
+ @qbc.addRecord(dbid,@qbc.fvlist)
75
+ entryField.value = ""
76
+ }
77
+ elsif numTextLines > 1
78
+ entryField = TkText.new(frame){
79
+ height numTextLines
80
+ width 60
81
+ font "Arial 10 bold"
82
+ pack "fill" => "both", "expand" => true, "side" => "top", "padx" =>5, "pady"=>5
83
+ wrap "word"
84
+ }
85
+ end
86
+ entryField.focus
87
+
88
+ buttonFrame = TkFrame.new(frame){
89
+ pack "side" => "bottom"
90
+ width 50
91
+ }
92
+ sendButton = TkButton.new(buttonFrame){
93
+ text "Send To QuickBase"
94
+ underline 0
95
+ font "Arial 10 bold"
96
+ pack "side"=>"left", "padx"=>5, "pady"=>5
97
+ }
98
+ sendButton.command {
99
+ if numTextLines > 1
100
+ value = entryField.get("1.0","end")
101
+ else
102
+ value = entryField.get
103
+ end
104
+ @qbc.clearFieldValuePairList
105
+ @qbc.addFieldValuePair(nil,fieldID,nil,value)
106
+ @qbc.addRecord(dbid,@qbc.fvlist)
107
+ entryField.value = ""
108
+ }
109
+ launchButton = TkButton.new(buttonFrame){
110
+ text "Go to QuickBase..."
111
+ underline 0
112
+ font "Arial 10 bold"
113
+ pack "side"=>"left","padx"=>5, "pady"=>5
114
+ }
115
+ launchButton .command {
116
+ url = "http://www.quickbase.com/db/#{dbid}"
117
+ url = "start #{url}" if RUBY_PLATFORM.split("-")[1].include?("mswin")
118
+ system(url)
119
+ }
120
+ closeButton = TkButton.new(buttonFrame){
121
+ text "Close"
122
+ underline 0
123
+ font "Arial 10 bold"
124
+ pack "side"=>"right","padx"=>5, "pady"=>5
125
+ }
126
+ closeButton.command { Tk.exit }
127
+
128
+ root.bind('Alt-KeyRelease-s') {|e| sendButton.invoke }
129
+ root.bind('Alt-KeyRelease-l') {|e| launchButton.invoke }
130
+ root.bind('Alt-KeyRelease-c') {|e| closeButton.invoke }
131
+
132
+ Tk.mainloop
133
+ else
134
+ Tk.messageBox({"icon"=>"error","title"=>"Oops!", "message" => "Error finding the QuickBase field '#{fieldName}' in the '#{tableName}' table."})
135
+ end
136
+ else
137
+ Tk.messageBox({"icon"=>"error","title"=>"Oops!", "message" => "Error finding the QuickBase table with the '#{dbid}' id."})
138
+ end
139
+ else
140
+ Tk.messageBox({"icon"=>"error","title"=>"Oops!", "message" => "Error connecting to QuickBase.\nPlease check your internet connection and your username and password."})
141
+ end
142
+ end
143
+
144
+ if ARGV[3]
145
+ runFieldEntryDialog(ARGV[0],ARGV[1],ARGV[2],ARGV[3..-1])
146
+ else
147
+ puts "\nusage: ruby runFieldEntryDialog.rb username password dbid field"
148
+ puts "\n'dbid' must be a valid table id."
149
+ puts "'field' must be the name or id of a text field in the 'dbid' table."
150
+ puts "'field' can be more than one word, e.g. 'To-Do Item'.\n"
151
+ end