nakor 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,4 +1,6 @@
1
1
  *.gem
2
+ *.swp
2
3
  .bundle
3
4
  Gemfile.lock
4
5
  pkg/*
6
+ tmp/*
@@ -0,0 +1,36 @@
1
+ # Nakor
2
+
3
+ Nakor is a Ruby gem for generating a template application for Corona SDK. It creates a template app with a splash screen, a menu with four buttons (Play, Settings, Help, About), and one scene for each of the four buttons. It uses Corona SDK's built-in Storyboard to manage scenes.
4
+
5
+ The generated app also includes [RadLib](https://github.com/radamanthus/radlib), a library of utility Lua functions to support Corona SDK development.
6
+
7
+ # Installation
8
+
9
+ gem install nakor
10
+
11
+
12
+ # Usage
13
+
14
+ nakor generate awesome_app
15
+
16
+ This will create the *awesome_app* directory in the current directory. To run it in Corona simulator:
17
+
18
+ cd awesome_app
19
+ /Applications/CoronaSDK/simulator awesome_app
20
+
21
+ The generated project directory structure looks like this:
22
+
23
+ appname
24
+ +-- assets
25
+ +-- appname
26
+ +-- doc
27
+ +-- server
28
+
29
+ The directory structure follows my personal convention for mobile projects:
30
+
31
+ - All mobile app code is in appname/appname.
32
+ - If this has a server component, the server app source code is in appname/server
33
+ - Game assets (e.g. Illustrator .ai files) are in appname/assets, finished PNGs are copied over to appname/appname because that's where Corona SDK expects them to be.
34
+ - The game design document (yes you should have one) and all other documentation are in appname/doc
35
+
36
+
data/Rakefile CHANGED
@@ -1,3 +1,2 @@
1
1
  require "bundler/gem_tasks"
2
2
 
3
- require "metric_fu"
@@ -1,12 +1,18 @@
1
1
  Feature: Generate
2
2
  In order to make the world a better place
3
- As a CLI
3
+ As a Corona SDK programmer
4
4
  I want to be able to generate new apps
5
5
 
6
- Scenario: Generate a new app in a non-existing folder
7
- When I run `../../bin/nakor generate awesome_game`
6
+ Scenario: Generate a new app in a non-existent folder
7
+ When I run `../../bin/nakor generate 'awesome_game'`
8
8
  Then the output should contain "Successfully generated 'awesome_game'"
9
9
  And the following files should exist:
10
10
  | awesome_game/main.lua |
11
11
 
12
12
  Scenario: Warn the user when generating an app will overwrite an existing folder
13
+
14
+ Scenario: Run the generated app
15
+ When I run `../../bin/nakor generate 'awesome_game'`
16
+ And I run `simulator awesome_game` interactively
17
+ Then the "awesome_game" app should run without errors
18
+
@@ -0,0 +1,4 @@
1
+ Then /^the "([^"]*)" app should run without errors$/ do |app_name|
2
+ # How do we test this?
3
+ pending
4
+ end
@@ -0,0 +1,19 @@
1
+ Feature: Generate
2
+ In order to make the world a better place
3
+ As a Corona SDK programmer
4
+ I want to be able to update my apps to the latest version of RadLib
5
+
6
+ Scenario: Refuse to update a non-existen app
7
+
8
+ Scenario: Update RadLib inside an existing app
9
+ When I run `../../bin/nakor update_radlib 'awesome_game'`
10
+ Then the output should contain "Successfully updated 'awesome_game'"
11
+ And the following files should exist:
12
+ | awesome_game/main.lua |
13
+
14
+ Scenario: Run the generated app
15
+ When I run `../../bin/nakor update_radlib 'awesome_game'`
16
+ And I run `simulator awesome_game` interactively
17
+ Then the "awesome_game" app should run without errors
18
+
19
+
@@ -7,5 +7,10 @@ module Nakor
7
7
  def generate(app_name)
8
8
  Nakor::Generators::App.start([app_name])
9
9
  end
10
+
11
+ desc "update_radlib APP_DIR", "updates radlib inside an existing application"
12
+ def update_radlib(app_dir)
13
+ Nakor::Utilities::UpdateRadLib.execute([app_dir])
14
+ end
10
15
  end
11
16
  end
@@ -17,19 +17,23 @@ module Nakor
17
17
 
18
18
  TEMPLATE_FILES = %W{
19
19
  about.lua
20
+ active_record.lua
20
21
  build.settings
21
22
  config.lua
23
+ geometry.lua
22
24
  help.lua
23
25
  init_buttons.lua
24
26
  io_ext.lua
25
27
  loadmenu.lua
26
28
  main.lua
27
29
  menu.lua
30
+ middleclass.lua
28
31
  orm.lua
29
32
  play.lua
30
33
  radlib.lua
31
34
  README
32
35
  settings.lua
36
+ sql.lua
33
37
  string_ext.lua
34
38
  table_ext.lua
35
39
  time_ext.lua
@@ -46,24 +50,37 @@ module Nakor
46
50
  end
47
51
 
48
52
  def create_group
49
- empty_directory(app_name)
53
+ # Create the top-level app directory
54
+ empty_directory app_name
55
+
56
+ # Create the subdirectories
57
+ create_subdirectory app_name
58
+ create_subdirectory "server"
59
+ create_subdirectory "assets"
60
+ create_subdirectory "doc"
50
61
  end
51
62
 
52
63
  def copy_source_files
53
64
  TEMPLATE_FILES.each do |template_file|
54
- template template_file, "#{app_name}/#{template_file}"
65
+ template template_file, "#{app_name}/#{app_name}/#{template_file}"
55
66
  end
56
67
  end
57
68
 
58
69
  def copy_asset_files
59
70
  ASSET_FILES.each do |asset_file|
60
- copy_file asset_file, "#{app_name}/#{asset_file}"
71
+ copy_file asset_file, "#{app_name}/#{app_name}/#{asset_file}"
61
72
  end
62
73
  end
63
74
 
64
75
  def done
65
76
  puts "Successfully generated '#{app_name}'"
66
77
  end
78
+
79
+ private
80
+
81
+ def create_subdirectory(subdir)
82
+ empty_directory(File.join app_name, subdir)
83
+ end
67
84
  end
68
85
  end
69
86
  end
@@ -0,0 +1,155 @@
1
+ -- USAGE
2
+ --
3
+ -- Create a Lua file for your module. The file should look like this:
4
+ --
5
+ -- require 'ActiveRecord'
6
+ -- Product = ActiveRecord:subclass('ActiveRecord')
7
+ -- Product.tableName = 'products'
8
+ -- Product.tableFields = {
9
+ -- id = {type = 'integer', flags = {'primary_key', 'autoincrement', 'not_null'} },
10
+ -- name = {type = 'string', flags = {'not_null'} }
11
+ -- }
12
+ --
13
+ -- If the table does not yet exist, you can create it in your app initialization with this call:
14
+ --
15
+ -- orm.initialize()
16
+ -- Product.createTable()
17
+ --
18
+ -- Sample API calls
19
+ --
20
+ -- local products = Product.findAll
21
+ --
22
+ -- p = Product.new{id = 1, name = 'test', description = ''} (NOT YET IMPLEMENTED)
23
+ -- p.save
24
+ --
25
+ -- p.updateAttribute('name', 'newName')
26
+ -- p.updateAttributes{name = 'newName', description = 'newDescription'} (NOT YET IMPLEMENTED)
27
+ --
28
+ -- p = Product.find(1)
29
+ -- test_products = Product.where("name = 'test'")
30
+ --
31
+ -- numberOfProducts = Product.count()
32
+ --
33
+
34
+ require 'middleclass'
35
+ local orm = require 'orm'
36
+ local sql = require 'sql'
37
+
38
+ ActiveRecord = class('ActiveRecord')
39
+
40
+ ------------------------------------------------------------------------------
41
+ -- CLASS (STATIC) METHODS - START
42
+ ------------------------------------------------------------------------------
43
+ function ActiveRecord:initialize(newRecord)
44
+ for k,v in pairs(newRecord) do
45
+ self[k] = v
46
+ end
47
+ end
48
+
49
+ ------------------------------------------------------------------------------
50
+ -- Returns the number of rows in the table
51
+ ------------------------------------------------------------------------------
52
+ function ActiveRecord.static:count()
53
+ return orm.getTableRowCount(self.tableName)
54
+ end
55
+
56
+ ------------------------------------------------------------------------------
57
+ -- Creates the table
58
+ -- TODO: If options.recreate = true, it drops the table if it already exists
59
+ ------------------------------------------------------------------------------
60
+ function ActiveRecord.static:createTable(options)
61
+ local createSql = sql.generateCreateTable(self.tableName, self.tableFields)
62
+ db:exec( createSql )
63
+ end
64
+
65
+ ------------------------------------------------------------------------------
66
+ -- Returns the record matching the given id. Returns nil if no match is found.
67
+ --
68
+ -- NOTE: Until I figure out how to determine the caller's class,
69
+ -- I'll have to resort to this ugliness of using the klass parameter
70
+ ------------------------------------------------------------------------------
71
+ function ActiveRecord.static:find(klass, id)
72
+ local record = orm.selectOne(klass.tableName, 'id', id)
73
+ if not( record == nil ) then
74
+ result = klass:new(record)
75
+ end
76
+ return result
77
+ end
78
+
79
+ ------------------------------------------------------------------------------
80
+ -- Returns all rows in the table that match the given filter
81
+ ------------------------------------------------------------------------------
82
+ function ActiveRecord.static:findAll( filter, orderBy )
83
+ local result = nil
84
+ if filter == nil then
85
+ result = orm.selectAll( self.tableName, {order = orderBy} )
86
+ else
87
+ result = orm.selectWhere( self.tableName, {where = filter, order = orderBy} )
88
+ end
89
+ return result
90
+ end
91
+
92
+ ------------------------------------------------------------------------------
93
+ -- Updates all rows in the table that match the given filter
94
+ ------------------------------------------------------------------------------
95
+ function ActiveRecord.static:updateAll( updateSql, filter )
96
+ if filter == nil then
97
+ orm.updateAll( self.tableName, updateSql )
98
+ else
99
+ orm.updateWhere( self.tableName, updateSql, filter )
100
+ end
101
+ end
102
+
103
+ ------------------------------------------------------------------------------
104
+ -- CLASS (STATIC) METHODS - END
105
+ ------------------------------------------------------------------------------
106
+
107
+
108
+ ------------------------------------------------------------------------------
109
+ -- INSTANCE METHODS - START
110
+ ------------------------------------------------------------------------------
111
+
112
+ ------------------------------------------------------------------------------
113
+ -- Reloads the record values from the database
114
+ ------------------------------------------------------------------------------
115
+ function ActiveRecord:reload()
116
+ local updatedRecord = orm.selectOne( self.class.tableName, 'id', self.id )
117
+ for k,v in pairs(updatedRecord) do
118
+ self[k] = v
119
+ end
120
+ end
121
+
122
+ ------------------------------------------------------------------------------
123
+ -- Saves the content of the object to the database.
124
+ -- If a matching record already exists in the database, an UPDATE is done.
125
+ -- Otherwise an INSERT is done.
126
+ ------------------------------------------------------------------------------
127
+ function ActiveRecord:save()
128
+ local updateTable = {}
129
+ for k in pairs(self.class.tableFields) do
130
+ updateTable[k] = self[k]
131
+ end
132
+ orm.createOrUpdate( self.class.tableName, updateTable )
133
+ end
134
+
135
+ ------------------------------------------------------------------------------
136
+ -- Updates one column value
137
+ ------------------------------------------------------------------------------
138
+ function ActiveRecord:updateAttribute( columnName, columnValue )
139
+ local filter = "id = " .. self.id
140
+ orm.updateAttribute( self.class.tableName, filter, columnName, columnValue )
141
+ end
142
+
143
+ ------------------------------------------------------------------------------
144
+ -- Updates an array of columns
145
+ ------------------------------------------------------------------------------
146
+ function ActiveRecord:updateAttributes( updateTable )
147
+ print("IMPLEMENTATION PENDING...")
148
+ end
149
+
150
+ ------------------------------------------------------------------------------
151
+ -- INSTANCE METHODS - END
152
+ ------------------------------------------------------------------------------
153
+
154
+
155
+
@@ -0,0 +1,76 @@
1
+ local M = {}
2
+
3
+ ------------------------------------------------------------
4
+ -- Public: checks if the given point is inside the given container
5
+ --
6
+ -- Assumptions:
7
+ -- The container has the properties: top, left, bottom, right
8
+ -- The point has the properties x, y
9
+ --
10
+ -- Returns:
11
+ -- true if the point is inside the container
12
+ -- false if not
13
+ ------------------------------------------------------------
14
+ local pointIsInside = function(point, rectangle)
15
+ if (
16
+ (point.x >= rectangle.left) and
17
+ (point.x <= rectangle.right) and
18
+ (point.y >= rectangle.top) and
19
+ (point.y <= rectangle.bottom)
20
+ ) then
21
+ return true
22
+ else
23
+ return false
24
+ end
25
+ end
26
+ M.pointIsInside = pointIsInside
27
+
28
+ ------------------------------------------------------------
29
+ -- Public: checks if the given rectangle is completely
30
+ -- inside the given rectangular container
31
+ --
32
+ -- Assumptions:
33
+ -- Both container and object have the properties: top, left, bottom, right
34
+ --
35
+ -- Returns:
36
+ -- true if the both (top,left) and (bottom,right)
37
+ -- of the rectangle are inside the container
38
+ -- false otherwise
39
+ ------------------------------------------------------------
40
+ local rectIsInside = function(object, container)
41
+ if pointIsInside({x = object.left, y = object.top}, container) and
42
+ pointIsInside({x = object.right, y = object.bottom}, container) then
43
+ return true
44
+ else
45
+ return false
46
+ end
47
+ end
48
+ M.rectIsInside = rectIsInside
49
+
50
+ ------------------------------------------------------------
51
+ -- Public: checks if the given rectangle is at at least partially
52
+ -- inside the given rectangular container
53
+ --
54
+ -- Assumption:
55
+ -- Both container and object have the properties: top, left, bottom, right
56
+ --
57
+ -- Returns:
58
+ -- true if at least one of the corners of the rectangle
59
+ -- is inside the container
60
+ -- false otherwise
61
+ ------------------------------------------------------------
62
+ local rectIsPartiallyInside = function(object, container)
63
+ if pointIsInside({x = object.left, y = object.top}, container) or
64
+ pointIsInside({x = object.right, y = object.top}, container) or
65
+ pointIsInside({x = object.left, y = object.bottom}, container) or
66
+ pointIsInside({x = object.right, y = object.bottom}, container) then
67
+ return true
68
+ else
69
+ return false
70
+ end
71
+ end
72
+ M.rectIsPartiallyInside = rectIsPartiallyInside
73
+
74
+ return M
75
+
76
+
@@ -0,0 +1,139 @@
1
+ -- middleclass.lua - v2.0 (2011-09)
2
+ -- Copyright (c) 2011 Enrique García Cota
3
+ -- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+ -- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
5
+ -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
6
+ -- Based on YaciCode, from Julien Patte and LuaObject, from Sebastien Rocca-Serra
7
+
8
+ local _classes = setmetatable({}, {__mode = "k"})
9
+
10
+ local function _setClassDictionariesMetatables(klass)
11
+ local dict = klass.__instanceDict
12
+ dict.__index = dict
13
+
14
+ local super = klass.super
15
+ if super then
16
+ local superStatic = super.static
17
+ setmetatable(dict, super.__instanceDict)
18
+ setmetatable(klass.static, { __index = function(_,k) return dict[k] or superStatic[k] end })
19
+ else
20
+ setmetatable(klass.static, { __index = function(_,k) return dict[k] end })
21
+ end
22
+ end
23
+
24
+ local function _setClassMetatable(klass)
25
+ setmetatable(klass, {
26
+ __tostring = function() return "class " .. klass.name end,
27
+ __index = klass.static,
28
+ __newindex = klass.__instanceDict,
29
+ __call = function(self, ...) return self:new(...) end
30
+ })
31
+ end
32
+
33
+ local function _createClass(name, super)
34
+ local klass = { name = name, super = super, static = {}, __mixins = {}, __instanceDict={} }
35
+ klass.subclasses = setmetatable({}, {__mode = "k"})
36
+
37
+ _setClassDictionariesMetatables(klass)
38
+ _setClassMetatable(klass)
39
+ _classes[klass] = true
40
+
41
+ return klass
42
+ end
43
+
44
+ local function _createLookupMetamethod(klass, name)
45
+ return function(...)
46
+ local method = klass.super[name]
47
+ assert( type(method)=='function', tostring(klass) .. " doesn't implement metamethod '" .. name .. "'" )
48
+ return method(...)
49
+ end
50
+ end
51
+
52
+ local function _setClassMetamethods(klass)
53
+ for _,m in ipairs(klass.__metamethods) do
54
+ klass[m]= _createLookupMetamethod(klass, m)
55
+ end
56
+ end
57
+
58
+ local function _setDefaultInitializeMethod(klass, super)
59
+ klass.initialize = function(instance, ...)
60
+ return super.initialize(instance, ...)
61
+ end
62
+ end
63
+
64
+ local function _includeMixin(klass, mixin)
65
+ assert(type(mixin)=='table', "mixin must be a table")
66
+ for name,method in pairs(mixin) do
67
+ if name ~= "included" and name ~= "static" then klass[name] = method end
68
+ end
69
+ if mixin.static then
70
+ for name,method in pairs(mixin.static) do
71
+ klass.static[name] = method
72
+ end
73
+ end
74
+ if type(mixin.included)=="function" then mixin:included(klass) end
75
+ klass.__mixins[mixin] = true
76
+ end
77
+
78
+ Object = _createClass("Object", nil)
79
+
80
+ Object.static.__metamethods = { '__add', '__call', '__concat', '__div', '__le', '__lt',
81
+ '__mod', '__mul', '__pow', '__sub', '__tostring', '__unm' }
82
+
83
+ function Object.static:allocate()
84
+ assert(_classes[self], "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'")
85
+ return setmetatable({ class = self }, self.__instanceDict)
86
+ end
87
+
88
+ function Object.static:new(...)
89
+ local instance = self:allocate()
90
+ instance:initialize(...)
91
+ return instance
92
+ end
93
+
94
+ function Object.static:subclass(name)
95
+ assert(_classes[self], "Make sure that you are using 'Class:subclass' instead of 'Class.subclass'")
96
+ assert(type(name) == "string", "You must provide a name(string) for your class")
97
+
98
+ local subclass = _createClass(name, self)
99
+ _setClassMetamethods(subclass)
100
+ _setDefaultInitializeMethod(subclass, self)
101
+ self.subclasses[subclass] = true
102
+ self:subclassed(subclass)
103
+
104
+ return subclass
105
+ end
106
+
107
+ function Object.static:subclassed(other) end
108
+
109
+ function Object.static:include( ... )
110
+ assert(_classes[self], "Make sure you that you are using 'Class:include' instead of 'Class.include'")
111
+ for _,mixin in ipairs({...}) do _includeMixin(self, mixin) end
112
+ return self
113
+ end
114
+
115
+ function Object:initialize() end
116
+
117
+ function Object:__tostring() return "instance of " .. tostring(self.class) end
118
+
119
+ function class(name, super, ...)
120
+ super = super or Object
121
+ return super:subclass(name, ...)
122
+ end
123
+
124
+ function instanceOf(aClass, obj)
125
+ if not _classes[aClass] or type(obj) ~= 'table' or not _classes[obj.class] then return false end
126
+ if obj.class == aClass then return true end
127
+ return subclassOf(aClass, obj.class)
128
+ end
129
+
130
+ function subclassOf(other, aClass)
131
+ if not _classes[aClass] or not _classes[other] or aClass.super == nil then return false end
132
+ return aClass.super == other or subclassOf(other, aClass.super)
133
+ end
134
+
135
+ function includes(mixin, aClass)
136
+ if not _classes[aClass] then return false end
137
+ if aClass.__mixins[mixin] then return true end
138
+ return includes(mixin, aClass.super)
139
+ end
@@ -1,3 +1,4 @@
1
+ local sql = require 'sql'
1
2
  local sqlite3 = require "sqlite3"
2
3
  local radlib = require "radlib"
3
4
 
@@ -9,9 +10,9 @@ local M = {}
9
10
  ------------------------------------------------------------------------------
10
11
  local initialize = function( dbPath )
11
12
  if dbPath ~= nil then
12
- db = sqlite3.open( dbPath )
13
+ _G.db = sqlite3.open( dbPath )
13
14
  else
14
- db = sqlite3.open_memory()
15
+ _G.db = sqlite3.open_memory()
15
16
  end
16
17
  return db
17
18
  end
@@ -21,16 +22,21 @@ M.initialize = initialize
21
22
  -- Close the database
22
23
  ------------------------------------------------------------------------------
23
24
  local close = function()
24
- db:close()
25
+ _G.db:close()
25
26
  end
26
27
  M.close = close
27
28
 
28
29
  ------------------------------------------------------------------------------
29
30
  -- Return all the contents of an SQLite table as a table structure
30
31
  ------------------------------------------------------------------------------
31
- local selectAll = function(tableName)
32
+ local selectAll = function( tableName, params )
32
33
  local result = {}
33
- for row in db:nrows("SELECT * FROM " .. tableName) do
34
+ local s = sql.generateSelect({
35
+ tableName = tableName,
36
+ order = params.order,
37
+ limit = params.limit
38
+ })
39
+ for row in _G.db:nrows(s) do
34
40
  result[#result+1] = row
35
41
  end
36
42
  return result
@@ -41,9 +47,15 @@ M.selectAll = selectAll
41
47
  -- Return contents of an SQLite table filtered by a WHERE query
42
48
  -- Return value is a table structure
43
49
  ------------------------------------------------------------------------------
44
- local selectWhere = function(tableName, whereClause)
50
+ local selectWhere = function(tableName, params )
45
51
  local result = {}
46
- for row in db:nrows("SELECT * FROM " .. tableName .. " WHERE " .. whereClause) do
52
+ local s = sql.generateSelect({
53
+ tableName = tableName,
54
+ where = params.where,
55
+ order = params.order,
56
+ limit = params.limit
57
+ })
58
+ for row in _G.db:nrows(s) do
47
59
  result[#result+1] = row
48
60
  end
49
61
  return result
@@ -56,10 +68,12 @@ M.selectWhere = selectWhere
56
68
  ------------------------------------------------------------------------------
57
69
  local selectOne = function(tableName, key, keyValue)
58
70
  local result = {}
59
- for row in db:nrows(
60
- "SELECT * FROM " .. tableName ..
61
- " WHERE " .. key .. " = " .. keyValue ..
62
- " LIMIT 1") do
71
+ local s = sql.generateSelect({
72
+ tableName = tableName,
73
+ where = key .. " = " .. keyValue,
74
+ limit = 1
75
+ })
76
+ for row in _G.db:nrows(s) do
63
77
  result[1] = row
64
78
  break
65
79
  end
@@ -72,7 +86,7 @@ M.selectOne = selectOne
72
86
  ------------------------------------------------------------------------------
73
87
  local getTableRowCount = function(tableName)
74
88
  local rowCount = 0
75
- for row in db:nrows("SELECT COUNT(*) as rowcount FROM " .. tableName) do
89
+ for row in _G.db:nrows("SELECT COUNT(*) as rowcount FROM " .. tableName) do
76
90
  rowCount = row.rowcount
77
91
  end
78
92
  return rowCount
@@ -107,8 +121,7 @@ local insertRow = function( tableName, row )
107
121
  local sql = "INSERT INTO " .. tableName .. columnList .. valuesList
108
122
 
109
123
  -- execute the SQL command for inserting the row
110
- print("Running INSERT SQL: " .. sql)
111
- db:exec( sql )
124
+ _G.db:exec( sql )
112
125
  end
113
126
  M.insertRow = insertRow
114
127
 
@@ -134,7 +147,6 @@ local updateRow = function( tableName, recordData )
134
147
  updateStr = string.sub( updateStr, 1, #updateStr-1 )
135
148
 
136
149
  local sql = "UPDATE " .. tableName .. " SET " .. updateStr .. " WHERE id = " .. recordData.id
137
- print( "UPDATE SQL: " .. sql )
138
150
  db:exec( sql )
139
151
  end
140
152
  M.updateRow = updateRow
@@ -153,6 +165,16 @@ local createOrUpdate = function( tableName, recordData )
153
165
  end
154
166
  M.createOrUpdate = createOrUpdate
155
167
 
168
+ ------------------------------------------------------------------------------
169
+ -- Updates all rows in the given table
170
+ ------------------------------------------------------------------------------
171
+ local updateAll = function( tablename, updateSql )
172
+ local str = "UPDATE " .. tablename ..
173
+ " SET " .. updateSql
174
+ db:exec( str )
175
+ end
176
+ M.updateAll = updateAll
177
+
156
178
  ------------------------------------------------------------------------------
157
179
  -- Updates one column for one row in a given table
158
180
  ------------------------------------------------------------------------------
@@ -163,7 +185,6 @@ local updateAttribute = function( tablename, filter, columnName, columnValue )
163
185
  local updateStr = "UPDATE " .. tablename ..
164
186
  " SET " .. columnName .. " = " .. columnValue ..
165
187
  " WHERE " .. filter
166
- print("UPDATE SQL: " .. updateStr )
167
188
  db:exec( updateStr )
168
189
  end
169
190
  M.updateAttribute = updateAttribute
@@ -185,7 +206,6 @@ local updateAttributes = function( tablename, filter, columns, columnValues )
185
206
  updateStr = updateStr .. ", "
186
207
  end
187
208
  end
188
- print("UPDATE SQL: " .. updateStr)
189
209
  db:exec(
190
210
  "UPDATE " .. tablename .. " SET " ..
191
211
  updateStr ..
@@ -194,5 +214,17 @@ local updateAttributes = function( tablename, filter, columns, columnValues )
194
214
  end
195
215
  M.updateAttributes = updateAttributes
196
216
 
217
+ ------------------------------------------------------------------------------
218
+ -- Updates all rows that match the filter in the given table
219
+ ------------------------------------------------------------------------------
220
+ local updateWhere = function( tablename, updateSql, filter )
221
+ local str = "UPDATE " .. tablename ..
222
+ " SET " .. updateSql ..
223
+ " WHERE " .. filter
224
+ db:exec( str )
225
+ end
226
+ M.updateWhere = updateWhere
227
+
228
+
197
229
  return M
198
230
 
@@ -2,6 +2,9 @@
2
2
 
3
3
  local M = {}
4
4
 
5
+ local geometry = require "geometry"
6
+ M.geometry = geometry
7
+
5
8
  local ioExt = require "io_ext"
6
9
  M.io = ioExt
7
10
 
@@ -14,7 +17,6 @@ M.table = tableExt
14
17
  local timeExt = require "time_ext"
15
18
  M.time = timeExt
16
19
 
17
-
18
20
  local debug = function( msg )
19
21
  native.showAlert("DEBUG", msg, {"OK"})
20
22
  end
@@ -0,0 +1,79 @@
1
+ ------------------------------------------------------------------------------
2
+ -- Module for SQL generation
3
+ ------------------------------------------------------------------------------
4
+ local _ = require 'underscore'
5
+ local string_ext = require 'string_ext'
6
+
7
+ local M = {}
8
+ ------------------------------------------------------------------------------
9
+ -- Generate the sql for the given field def flags
10
+ ------------------------------------------------------------------------------
11
+ local sqlForFieldFlags = function(fieldDef)
12
+ if fieldDef.flags ~= nil then
13
+ return _.join(fieldDef.flags, ' '):upper()
14
+ else
15
+ return ''
16
+ end
17
+ end
18
+ M.sqlForFieldFlags = sqlForFieldFlags
19
+
20
+ ------------------------------------------------------------------------------
21
+ -- Generate a CREATE TABLE IF NOT EXISTS statement
22
+ -- for the given tablename and tablefield definitions
23
+ ------------------------------------------------------------------------------
24
+ local generateCreateTable = function(tableName, tableFields)
25
+ local result = ''
26
+ result = 'CREATE TABLE IF NOT EXISTS ' .. tableName .. '('
27
+ for fieldName,fieldDef in pairs(tableFields) do
28
+ result = result .. string_ext.doubleQuote(fieldName) .. ' ' .. fieldDef.dataType:upper()
29
+ result = result .. ' ' .. M.sqlForFieldFlags(fieldDef)
30
+ result = result .. ','
31
+ end
32
+ result = string.sub( result, 1, result:len()-1 )
33
+ result = result .. ')'
34
+ return result
35
+ end
36
+ M.generateCreateTable = generateCreateTable
37
+
38
+ ------------------------------------------------------------------------------
39
+ -- Generate a SELECT statement
40
+ --
41
+ -- Parameters:
42
+ -- tableName
43
+ -- columns
44
+ -- where
45
+ -- order
46
+ -- limit
47
+ ------------------------------------------------------------------------------
48
+ local generateSelect = function(params)
49
+ local tableName = ''
50
+ if params.tableName == nil or params.tableName == '' then
51
+ return ''
52
+ else
53
+ tableName = params.tableName
54
+ end
55
+
56
+ local columns = ''
57
+ if params.columns == nil or params.columns == '' then
58
+ columns = '*'
59
+ else
60
+ columns = params.columns
61
+ end
62
+
63
+ local result = ''
64
+ result = 'SELECT ' .. columns .. ' FROM ' .. tableName
65
+ if params.where ~= nil and params.where ~= '' then
66
+ result = result .. ' WHERE ' .. params.where
67
+ end
68
+ if params.order ~= nil and params.order ~= '' then
69
+ result = result .. ' ORDER BY ' .. params.order
70
+ end
71
+ if params.limit ~= nil and params.limit ~= '' then
72
+ result = result .. ' LIMIT ' .. params.limit
73
+ end
74
+ return result
75
+ end
76
+ M.generateSelect = generateSelect
77
+
78
+
79
+ return M
@@ -0,0 +1,9 @@
1
+ require 'thor/group'
2
+ module Nakor
3
+ module Utilities
4
+ module UpdateRadLib
5
+ def execute(options=[])
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module Nakor
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
@@ -32,6 +32,5 @@ Gem::Specification.new do |s|
32
32
 
33
33
  s.add_development_dependency "aruba"
34
34
  s.add_development_dependency "cucumber"
35
- s.add_development_dependency "metric_fu"
36
35
  s.add_development_dependency "rspec"
37
36
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nakor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-21 00:00:00.000000000 Z
12
+ date: 2012-07-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
16
- requirement: &70361459079340 !ruby/object:Gem::Requirement
16
+ requirement: &70127996041500 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70361459079340
24
+ version_requirements: *70127996041500
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: aruba
27
- requirement: &70361459078220 !ruby/object:Gem::Requirement
27
+ requirement: &70127996040980 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70361459078220
35
+ version_requirements: *70127996040980
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: cucumber
38
- requirement: &70361459076920 !ruby/object:Gem::Requirement
38
+ requirement: &70127996040480 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,21 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70361459076920
47
- - !ruby/object:Gem::Dependency
48
- name: metric_fu
49
- requirement: &70361594269960 !ruby/object:Gem::Requirement
50
- none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- type: :development
56
- prerelease: false
57
- version_requirements: *70361594269960
46
+ version_requirements: *70127996040480
58
47
  - !ruby/object:Gem::Dependency
59
48
  name: rspec
60
- requirement: &70361594269540 !ruby/object:Gem::Requirement
49
+ requirement: &70127996039980 !ruby/object:Gem::Requirement
61
50
  none: false
62
51
  requirements:
63
52
  - - ! '>='
@@ -65,7 +54,7 @@ dependencies:
65
54
  version: '0'
66
55
  type: :development
67
56
  prerelease: false
68
- version_requirements: *70361594269540
57
+ version_requirements: *70127996039980
69
58
  description: ! "\n To create a new Corona SDK game using nakor, just run:\n\n nakor
70
59
  generate awesome_game\n\n This will create an awesome_game directory in the current
71
60
  directory, and copy all corona game template files into it.\n\n To run the generated
@@ -79,16 +68,20 @@ extra_rdoc_files: []
79
68
  files:
80
69
  - .gitignore
81
70
  - Gemfile
71
+ - README.md
82
72
  - Rakefile
83
73
  - bin/nakor
84
74
  - features/generate.feature
75
+ - features/step_definitions/generate_steps.rb
85
76
  - features/support/setup.rb
77
+ - features/update.feature
86
78
  - lib/nakor.rb
87
79
  - lib/nakor/app.rb
88
80
  - lib/nakor/cli.rb
89
81
  - lib/nakor/generators/app.rb
90
82
  - lib/nakor/generators/corona-game-template/README
91
83
  - lib/nakor/generators/corona-game-template/about.lua
84
+ - lib/nakor/generators/corona-game-template/active_record.lua
92
85
  - lib/nakor/generators/corona-game-template/bk_default.png
93
86
  - lib/nakor/generators/corona-game-template/btn_about.png
94
87
  - lib/nakor/generators/corona-game-template/btn_about_over.png
@@ -100,22 +93,26 @@ files:
100
93
  - lib/nakor/generators/corona-game-template/btn_settings_over.png
101
94
  - lib/nakor/generators/corona-game-template/build.settings
102
95
  - lib/nakor/generators/corona-game-template/config.lua
96
+ - lib/nakor/generators/corona-game-template/geometry.lua
103
97
  - lib/nakor/generators/corona-game-template/help.lua
104
98
  - lib/nakor/generators/corona-game-template/init_buttons.lua
105
99
  - lib/nakor/generators/corona-game-template/io_ext.lua
106
100
  - lib/nakor/generators/corona-game-template/loadmenu.lua
107
101
  - lib/nakor/generators/corona-game-template/main.lua
108
102
  - lib/nakor/generators/corona-game-template/menu.lua
103
+ - lib/nakor/generators/corona-game-template/middleclass.lua
109
104
  - lib/nakor/generators/corona-game-template/orm.lua
110
105
  - lib/nakor/generators/corona-game-template/play.lua
111
106
  - lib/nakor/generators/corona-game-template/radlib.lua
112
107
  - lib/nakor/generators/corona-game-template/settings.lua
113
108
  - lib/nakor/generators/corona-game-template/splash_screen.png
109
+ - lib/nakor/generators/corona-game-template/sql.lua
114
110
  - lib/nakor/generators/corona-game-template/string_ext.lua
115
111
  - lib/nakor/generators/corona-game-template/table_ext.lua
116
112
  - lib/nakor/generators/corona-game-template/time_ext.lua
117
113
  - lib/nakor/generators/corona-game-template/ui.lua
118
114
  - lib/nakor/generators/corona-game-template/underscore.lua
115
+ - lib/nakor/utilities/update_rad_lib.rb
119
116
  - lib/nakor/version.rb
120
117
  - nakor.gemspec
121
118
  - spec/app_spec.rb
@@ -139,11 +136,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
136
  version: '0'
140
137
  requirements: []
141
138
  rubyforge_project: nakor
142
- rubygems_version: 1.8.10
139
+ rubygems_version: 1.8.17
143
140
  signing_key:
144
141
  specification_version: 3
145
142
  summary: Nakor is a gem that encapsulates the corona-game-template project.
146
143
  test_files:
147
144
  - features/generate.feature
145
+ - features/step_definitions/generate_steps.rb
148
146
  - features/support/setup.rb
147
+ - features/update.feature
149
148
  - spec/app_spec.rb