mysql Lua+ffi binding http://luapower.com/mysql
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
2.9KB

  1. --mysql table pretty printing
  2. if not ... then require'mysql_test'; return end
  3. local function ellipsis(s,n)
  4. return #s > n and (s:sub(1,n-3) .. '...') or s
  5. end
  6. local align = {}
  7. function align.left(s,n)
  8. s = s..(' '):rep(n - #s)
  9. return ellipsis(s,n)
  10. end
  11. function align.right(s,n)
  12. s = (' '):rep(n - #s)..s
  13. return ellipsis(s,n)
  14. end
  15. function align.center(s,n)
  16. local total = n - #s
  17. local left = math.floor(total / 2)
  18. local right = math.ceil(total / 2)
  19. s = (' '):rep(left)..s..(' '):rep(right)
  20. return ellipsis(s,n)
  21. end
  22. local function fit(s,n,al)
  23. return align[al or 'left'](s,n)
  24. end
  25. local function print_table(fields, rows, aligns, minsize, print)
  26. print = print or _G.print
  27. minsize = minsize or math.huge
  28. local max_sizes = {}
  29. for i=1,#rows do
  30. for j=1,#fields do
  31. max_sizes[j] = math.min(minsize, math.max(max_sizes[j] or 0, #rows[i][j]))
  32. end
  33. end
  34. local totalsize = 0
  35. for j=1,#fields do
  36. max_sizes[j] = math.max(max_sizes[j] or 0, #fields[j])
  37. totalsize = totalsize + max_sizes[j] + 3
  38. end
  39. print()
  40. local s, ps = '', ''
  41. for j=1,#fields do
  42. s = s .. fit(fields[j], max_sizes[j], 'center') .. ' | '
  43. ps = ps .. ('-'):rep(max_sizes[j]) .. ' + '
  44. end
  45. print(s)
  46. print(ps)
  47. for i=1,#rows do
  48. local s = ''
  49. for j=1,#fields do
  50. local val = rows[i][j]
  51. s = s .. fit(val, max_sizes[j], aligns and aligns[j]) .. ' | '
  52. end
  53. print(s)
  54. end
  55. print()
  56. end
  57. local function invert_table(fields, rows, minsize)
  58. local ft, rt = {'field'}, {}
  59. for i=1,#rows do
  60. ft[i+1] = tostring(i)
  61. end
  62. for j=1,#fields do
  63. local row = {fields[j]}
  64. for i=1,#rows do
  65. row[i+1] = rows[i][j]
  66. end
  67. rt[j] = row
  68. end
  69. return ft, rt
  70. end
  71. local function format_cell(v)
  72. if v == nil then
  73. return 'NULL'
  74. else
  75. return tostring(v)
  76. end
  77. end
  78. local function cell_align(current_align, cell_value)
  79. if current_align == 'left' then return 'left' end
  80. if type(cell_value) == 'number' or type(cell_value) == 'cdata' then return 'right' end
  81. return 'left'
  82. end
  83. local function print_result(res, minsize, print)
  84. local fields = {}
  85. for i,field in res:fields() do
  86. fields[i] = field.name
  87. end
  88. local rows = {}
  89. local aligns = {} --deduced from values
  90. for i,row in res:rows'n' do
  91. local t = {}
  92. for j=1,#fields do
  93. t[j] = format_cell(row[j])
  94. aligns[j] = cell_align(aligns[j], row[j])
  95. end
  96. rows[i] = t
  97. end
  98. print_table(fields, rows, aligns, minsize, print)
  99. end
  100. local function print_statement(stmt, minsize, print)
  101. local res = stmt:bind_result()
  102. local fields = {}
  103. for i,field in stmt:fields() do
  104. fields[i] = field.name
  105. end
  106. local rows = {}
  107. local aligns = {}
  108. while stmt:fetch() do
  109. local row = {}
  110. for i=1,#fields do
  111. local v = res:get(i)
  112. row[i] = format_cell(v)
  113. aligns[i] = cell_align(aligns[i], v)
  114. end
  115. rows[#rows+1] = row
  116. end
  117. stmt:close()
  118. print_table(fields, rows, aligns, minsize, print)
  119. end
  120. return {
  121. fit = fit,
  122. format_cell = format_cell,
  123. table = print_table,
  124. result = print_result,
  125. statement = print_statement,
  126. }