Bonus Program Foxpro
Bonus Program Foxpro
In Chapter 19 we recommended that you not upsize the VFE security. However, it is hard to convince anyone that a client/server application is secure if the security information is readily accessible in DBF files on the file server which the users must be given full rights to.
The Visual Fox Express security system is very robust and configurable. As a matter of fact, we generally do not define any security beyond setting up the security names and giving our users access to the security screen. In this chapter I will give you the tools and information you need to move the tables to the server. The main caveat here is that the following has been done on SQL Server 7.0. If you are using another version or manufacturer youre on your own, however, we suspect the process will be very similar.
Tables
The first step is to move the security tables to your SQL database. There are several ways that you can do this. The first would be to use the upsizing wizard. This will get you started but not 100% of the way there. The VFE tables have several rules on them which the wizard doesnt handle very well. The second method you could use would be to script them by hand. This method will work well, if you like writing scripts. You could also use enterprise manager to create the tables. However, you are in luck, since I already created these tables for you. I generated a SQL script for you to create them. To run this script, copy it to the SQL Query Analyzer and run it. Be sure you have selected your applications database prior to running the script. The tables will be created with duplicates of all the DBC rules that VFE imposes on these tables.
ALTER TABLE [dbo].[apprites] DROP CONSTRAINT FK_apprites_cgroupd_id GO ALTER TABLE [dbo].[appusers] DROP CONSTRAINT FK_appusers_cgroupd_id GO /****** Object: Table [dbo].[appgroups] Script Date: 1/4/2001 11:17:00 AM ******/ if exists (select * from sysobjects where id = object_id(N'[dbo].[appgroups]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[appgroups] GO /****** Object: Table [dbo].[appinfo] Script Date: 1/4/2001 11:17:00 AM ******/ if exists (select * from sysobjects where id = object_id(N'[dbo].[appinfo]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[appinfo] GO /****** Object: Table [dbo].[applogin] Script Date: 1/4/2001 11:17:00 AM ******/ if exists (select * from sysobjects where id = object_id(N'[dbo].[applogin]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[applogin] GO /****** Object: Table [dbo].[appnames] Script Date: 1/4/2001 11:17:00 AM ******/ if exists (select * from sysobjects where id = object_id(N'[dbo].[appnames]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[appnames] GO /****** Object: Table [dbo].[apprites] Script Date: 1/4/2001 11:17:00 AM ******/ if exists (select * from sysobjects where id = object_id(N'[dbo].[apprites]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[apprites] GO /****** Object: Table [dbo].[appusers] Script Date: 1/4/2001 11:17:00 AM ******/ if exists (select * from sysobjects where id = object_id(N'[dbo].[appusers]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[appusers] GO /****** Object: Table [dbo].[appgroups] ******/ CREATE TABLE [dbo].[appgroups] ( [cgroup_id] [char] (16) NOT NULL , [cname] [char] (40) NOT NULL , [mdescript] [text] NOT NULL , [timestamp_column] [timestamp] NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO Script Date: 1/4/2001 11:17:06 AM
/****** Object: Table [dbo].[appinfo] Script Date: 1/4/2001 11:17:06 AM ******/ CREATE TABLE [dbo].[appinfo] ( [cid] [char] (16) NOT NULL , [nminpasswordlength] [numeric](2, 0) NOT NULL , [nminuseridlength] [numeric](2, 0) NOT NULL , [nmaxlogins] [numeric](2, 0) NOT NULL , [nfailures] [numeric](2, 0) NOT NULL , [luniquepassword] [bit] NOT NULL , [nchangepassword] [numeric](4, 0) NOT NULL , [ndefaultlevel] [numeric](1, 0) NOT NULL , [timestamp_column] [timestamp] NULL ) ON [PRIMARY] GO /****** Object: Table [dbo].[applogin] ******/ CREATE TABLE [dbo].[applogin] ( [cuserid] [char] (30) NOT NULL , [tloggedin] [datetime] NOT NULL , [tloggedout] [datetime] NULL , [tcleared] [datetime] NULL , [cclearedby] [char] (30) NOT NULL , [timestamp_column] [timestamp] NULL ) ON [PRIMARY] GO Script Date: 1/4/2001 11:17:07 AM
/****** Object: Table [dbo].[appnames] ******/ CREATE TABLE [dbo].[appnames] ( [cname] [char] (40) NOT NULL , [mdescription] [text] NOT NULL , [timestamp_column] [timestamp] NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO /****** Object: Table [dbo].[apprites] ******/ CREATE TABLE [dbo].[apprites] ( [cgroup_id] [char] (16) NOT NULL , [cname] [char] (40) NOT NULL , [nrights] [numeric](1, 0) NOT NULL , [timestamp_column] [timestamp] NULL ) ON [PRIMARY] GO /****** Object: Table [dbo].[appusers] ******/ CREATE TABLE [dbo].[appusers] ( [cuserid] [char] (30) NOT NULL , [cfirst_name] [char] (20) NULL , [clast_name] [char] (25) NULL , [cpassword] [char] (30) NOT NULL , [dlastchanged] [datetime] NOT NULL , [ladministrator] [bit] NOT NULL , [cgroup_id] [char] (16) NULL , [moldpasswords] [text] NOT NULL , [linactive] [bit] NOT NULL , [timestamp_column] [timestamp] NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO
ALTER TABLE [dbo].[appgroups] WITH NOCHECK ADD PRIMARY KEY CLUSTERED ( [cgroup_id] ) ON [PRIMARY] GO ALTER TABLE [dbo].[appinfo] WITH NOCHECK ADD PRIMARY KEY CLUSTERED ( [cid] ) ON [PRIMARY] GO ALTER TABLE [dbo].[appnames] WITH NOCHECK ADD PRIMARY KEY CLUSTERED ( [cname] ) ON [PRIMARY] GO ALTER TABLE [dbo].[apprites] WITH NOCHECK ADD CONSTRAINT [PK_apprites] PRIMARY KEY CLUSTERED ( [cgroup_id],
) GO
[cname] ON [PRIMARY]
ALTER TABLE [dbo].[appusers] WITH NOCHECK ADD CONSTRAINT [PK__appusers__2DF4EC6C] PRIMARY KEY ( [cuserid] ) ON [PRIMARY] GO
CLUSTERED
ALTER TABLE [dbo].[appinfo] WITH NOCHECK ADD CHECK ([nchangepassword] >= 0), CHECK ([ndefaultlevel] >= 1 and [ndefaultlevel] <= 3), CHECK ([nfailures] >= 3), CHECK ([nmaxlogins] >= 0), CHECK ([nminpasswordlength] >= 0), CHECK ([nminuseridlength] >= 0) GO ALTER TABLE [dbo].[applogin] WITH NOCHECK ADD CONSTRAINT [DF__applogin__tlogge__255FA66B] DEFAULT (getdate()) FOR [tloggedin], CONSTRAINT [DF__applogin__cclear__2653CAA4] DEFAULT ('') FOR [cclearedby] GO ALTER TABLE [dbo].[appnames] WITH NOCHECK ADD CONSTRAINT [DF__appnames__mdescr__2930374F] DEFAULT ('') FOR [mdescription] GO ALTER TABLE [dbo].[apprites] WITH NOCHECK ADD CONSTRAINT [DF__apprites__nright__2C0CA3FA] DEFAULT (0) FOR [nrights] GO ALTER TABLE [dbo].[appusers] WITH NOCHECK ADD CONSTRAINT [DF__appusers__cfirst__2EE910A5] DEFAULT CONSTRAINT [DF__appusers__clast___2FDD34DE] DEFAULT CONSTRAINT [DF_appusers_cpassword] DEFAULT ('') FOR CONSTRAINT [DF__appusers__dlastc__30D15917] DEFAULT [dlastchanged], CONSTRAINT [DF__appusers__ladmin__31C57D50] DEFAULT CONSTRAINT [DF_appusers_moldpasswords] DEFAULT ('') CONSTRAINT [DF__appusers__linact__32B9A189] DEFAULT GO ALTER TABLE [dbo].[apprites] ADD CONSTRAINT [FK_apprites_cgroupd_id] FOREIGN KEY ( [cgroup_id] ) REFERENCES [dbo].[appgroups] ( [cgroup_id] ) GO ALTER TABLE [dbo].[appusers] ADD CONSTRAINT [FK_appusers_cgroupd_id] FOREIGN KEY ( [cgroup_id] ) REFERENCES [dbo].[appgroups] ( [cgroup_id] ) ('') FOR [cfirst_name], ('') FOR [clast_name], [cpassword], (getdate()) FOR (0) FOR [ladministrator], FOR [moldpasswords], (0) FOR [linactive]
GO
When you run the above script you should get the message Execution Completed without error or similar in your results pane. If you browse your database in enterprise manager you will be able to verify that the tables have been created.
Remote Views
The second step is to create remote views to these tables in your FESYS database. The FESYS database is the database container file that VFE creates to stored the security tables and views. They are created in a separate database so that you can share your security tables with several applications if you wish, or also several data sets for a specific application. The first step to doing this is to create a connection for the remote views. As you know, a connection is the information VFP will use to connect to your SQL Server database. Once this connection is established it is utilized to send the remote view queries to the server. As we showed in the tips chapter you want to share the connection. However, your current connection was created in your applications .DBC file, and not in the FESYS file. We have verified that if you create a connection with the same name that connection will be shared between views in the separate databases. Once you have your connection created you will need to create the remote views which will be used by VFE to retrieve and update data. The views in FESYS are designed to use the LV_/RV_ prefix to views. If you are not familiar with this, what happens is that, based on a property in the application object, lUseLocalData the cursor class knows whether to open the LV_xxx view or the RV_xxx view. In both cases the view will be opened with an alias of V_xxx. What this means is that the first step creating the remote views is to set lUseLocalData to true in your application object. OK, at this point you have created your connection and set you lUseLocalData propert to false. Once again, I will make this easy for you. The following code will create the remote views for you. There are three things you need to do to run this: 1. Change the #DEFINE of the first line of code to the name of the connection that you have created in place of NameOfYourConnection. 2. At the command window open the FESYS database using the command OPEN DATABASE FESYS. 3. Run the code from the command window. You can either paste this code to a .PRG file or paste it to the command window to run it.
#DEFINE x_CONNECTION "NameOfYourConnection" * ********************************************************************* * * * * 1/3/2001 FESYS.DBC 12:26:07 * * * ********************************************************************* * * * * Description: * * This program was automatically generated by GenDBCX Version 1.1, * * a modified version of Microsoft's utility GenDBC Version 2.26.67. * * * ********************************************************************* **************************************************
** View setup for RV_GROUPS ************************************************** Create SQL VIEW "RV_GROUPS" REMOTE CONNECTION x_CONNECTION ; AS SELECT * FROM appgroups ORDER BY appgroups.cname =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', =DBSetProp('RV_GROUPS', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'UpdateType', 1) 'WhereType', 3) 'FetchMemo', .T.) 'SendUpdates', .T.) 'UseMemoSize', 255) 'FetchSize', 100) 'MaxRecords', -1) 'Tables', 'appgroups') 'FetchSize', 100) 'Comment', "") 'BatchUpdateCount', 1) 'ShareConnection', .T.) 'Prepared', .F.) 'CompareMemo', .T.) 'FetchAsNeeded', .F.)
*!* Field Level Properties for RV_GROUPS * Props for the RV_GROUPS.cgroup_id field. =DBSetProp('RV_GROUPS.cgroup_id', 'Field', 'KeyField', .T.) =DBSetProp('RV_GROUPS.cgroup_id', 'Field', 'Updatable', .T.) =DBSetProp('RV_GROUPS.cgroup_id', 'Field', 'UpdateName', 'appgroups.cgroup_id') =DBSetProp('RV_GROUPS.cgroup_id', 'Field', 'Caption', "Group Id") =DBSetProp('RV_GROUPS.cgroup_id', 'Field', 'DataType', "C(16) NOCPTRANS") =DBSetProp('RV_GROUPS.cgroup_id', 'Field', 'DefaultValue', "GUID()") * Props for the RV_GROUPS.cname field. =DBSetProp('RV_GROUPS.cname', 'Field', 'KeyField', .F.) =DBSetProp('RV_GROUPS.cname', 'Field', 'Updatable', .T.) =DBSetProp('RV_GROUPS.cname', 'Field', 'UpdateName', 'appgroups.cname') =DBSetProp('RV_GROUPS.cname', 'Field', 'RuleExpression', "NOT EMPTY(cname)") =DBSetProp('RV_GROUPS.cname', 'Field', 'RuleText', "'Group Name must be entered.'") =DBSetProp('RV_GROUPS.cname', 'Field', 'Caption', "Group Name") =DBSetProp('RV_GROUPS.cname', 'Field', 'DataType', "C(40)") * Props for the RV_GROUPS.mdescript field. =DBSetProp('RV_GROUPS.mdescript', 'Field', 'KeyField', .F.) =DBSetProp('RV_GROUPS.mdescript', 'Field', 'Updatable', .T.) =DBSetProp('RV_GROUPS.mdescript', 'Field', 'UpdateName', 'appgroups.mdescript') =DBSetProp('RV_GROUPS.mdescript', 'Field', 'RuleExpression', "NOT EMPTY( mdescript)") =DBSetProp('RV_GROUPS.mdescript', 'Field', 'RuleText', "'Description must be entered.'") =DBSetProp('RV_GROUPS.mdescript', 'Field', 'Caption', "Description") =DBSetProp('RV_GROUPS.mdescript', 'Field', 'DataType', "M") ************************************************** ** View setup for RV_CURRENTUSER ************************************************** Local vp_cUserId vp_cUserId = "A" Create SQL VIEW "RV_CURRENTUSER" REMOTE CONNECTION x_CONNECTION ; AS SELECT * FROM appusers WHERE appusers.cuserid = ?vp_cUserId =DBSetProp('RV_CURRENTUSER', 'View', 'UpdateType', 1) =DBSetProp('RV_CURRENTUSER', 'View', 'WhereType', 3)
=DBSetProp('RV_CURRENTUSER', =DBSetProp('RV_CURRENTUSER', =DBSetProp('RV_CURRENTUSER', =DBSetProp('RV_CURRENTUSER', =DBSetProp('RV_CURRENTUSER', =DBSetProp('RV_CURRENTUSER', =DBSetProp('RV_CURRENTUSER', =DBSetProp('RV_CURRENTUSER', =DBSetProp('RV_CURRENTUSER', =DBSetProp('RV_CURRENTUSER', =DBSetProp('RV_CURRENTUSER', =DBSetProp('RV_CURRENTUSER', =DBSetProp('RV_CURRENTUSER', =DBSetProp('RV_CURRENTUSER',
'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View',
'FetchMemo', .T.) 'SendUpdates', .T.) 'UseMemoSize', 255) 'FetchSize', 100) 'MaxRecords', -1) 'Tables', 'appusers') 'FetchSize', 100) 'ParameterList', "vp_cUserId,'C'") 'Comment', "") 'BatchUpdateCount', 1) 'ShareConnection', .T.) 'Prepared', .F.) 'CompareMemo', .T.) 'FetchAsNeeded', .F.)
*!* Field Level Properties for RV_CURRENTUSER * Props for the RV_CURRENTUSER.cuserid field. =DBSetProp('RV_CURRENTUSER.cuserid', 'Field', 'KeyField', .T.) =DBSetProp('RV_CURRENTUSER.cuserid', 'Field', 'Updatable', .T.) =DBSetProp('RV_CURRENTUSER.cuserid', 'Field', 'UpdateName', 'appusers.cuserid') =DBSetProp('RV_CURRENTUSER.cuserid', 'Field', 'DataType', "C(30)") * Props for the RV_CURRENTUSER.cfirst_name field. =DBSetProp('RV_CURRENTUSER.cfirst_name', 'Field', 'KeyField', .F.) =DBSetProp('RV_CURRENTUSER.cfirst_name', 'Field', 'Updatable', .T.) =DBSetProp('RV_CURRENTUSER.cfirst_name', 'Field', 'UpdateName', 'appusers.cfirst_name') =DBSetProp('RV_CURRENTUSER.cfirst_name', 'Field', 'DataType', "C(20)") * Props for the RV_CURRENTUSER.clast_name field. =DBSetProp('RV_CURRENTUSER.clast_name', 'Field', 'KeyField', .F.) =DBSetProp('RV_CURRENTUSER.clast_name', 'Field', 'Updatable', .T.) =DBSetProp('RV_CURRENTUSER.clast_name', 'Field', 'UpdateName', 'appusers.clast_name') =DBSetProp('RV_CURRENTUSER.clast_name', 'Field', 'DataType', "C(25)") * Props for the RV_CURRENTUSER.cpassword field. =DBSetProp('RV_CURRENTUSER.cpassword', 'Field', 'KeyField', .F.) =DBSetProp('RV_CURRENTUSER.cpassword', 'Field', 'Updatable', .T.) =DBSetProp('RV_CURRENTUSER.cpassword', 'Field', 'UpdateName', 'appusers.cpassword') =DBSetProp('RV_CURRENTUSER.cpassword', 'Field', 'DataType', "C(30)") * Props for the RV_CURRENTUSER.dlastchanged field. =DBSetProp('RV_CURRENTUSER.dlastchanged', 'Field', 'KeyField', .F.) =DBSetProp('RV_CURRENTUSER.dlastchanged', 'Field', 'Updatable', .T.) =DBSetProp('RV_CURRENTUSER.dlastchanged', 'Field', 'UpdateName', 'appusers.dlastchanged') =DBSetProp('RV_CURRENTUSER.dlastchanged', 'Field', 'DataType', "D") * Props for the RV_CURRENTUSER.ladministrator field. =DBSetProp('RV_CURRENTUSER.ladministrator', 'Field', 'KeyField', .F.) =DBSetProp('RV_CURRENTUSER.ladministrator', 'Field', 'Updatable', .T.) =DBSetProp('RV_CURRENTUSER.ladministrator', 'Field', 'UpdateName', 'appusers.ladministrator') =DBSetProp('RV_CURRENTUSER.ladministrator', 'Field', 'DataType', "L") * Props for the RV_CURRENTUSER.cgroup_id field. =DBSetProp('RV_CURRENTUSER.cgroup_id', 'Field', 'KeyField', .F.) =DBSetProp('RV_CURRENTUSER.cgroup_id', 'Field', 'Updatable', .T.) =DBSetProp('RV_CURRENTUSER.cgroup_id', 'Field', 'UpdateName', 'appusers.cgroup_id') =DBSetProp('RV_CURRENTUSER.cgroup_id', 'Field', 'DataType', "C(16) NOCPTRANS") * Props for the RV_CURRENTUSER.moldpasswords field. =DBSetProp('RV_CURRENTUSER.moldpasswords', 'Field', 'KeyField', .F.) =DBSetProp('RV_CURRENTUSER.moldpasswords', 'Field', 'Updatable', .T.) =DBSetProp('RV_CURRENTUSER.moldpasswords', 'Field', 'UpdateName', 'appusers.moldpasswords')
=DBSetProp('RV_CURRENTUSER.moldpasswords', 'Field', 'DataType', "M") * Props for the RV_CURRENTUSER.linactive field. =DBSetProp('RV_CURRENTUSER.linactive', 'Field', 'KeyField', .F.) =DBSetProp('RV_CURRENTUSER.linactive', 'Field', 'Updatable', .T.) =DBSetProp('RV_CURRENTUSER.linactive', 'Field', 'UpdateName', 'appusers.linactive') =DBSetProp('RV_CURRENTUSER.linactive', 'Field', 'DataType', "L") ************************************************** ** View setup for RV_LOGIN ************************************************** Create SQL VIEW "RV_LOGIN" REMOTE CONNECTION x_CONNECTION ; AS SELECT * FROM appusers ORDER BY appusers.cuserid =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', =DBSetProp('RV_LOGIN', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'UpdateType', 1) 'WhereType', 3) 'FetchMemo', .T.) 'SendUpdates', .T.) 'UseMemoSize', 255) 'FetchSize', 100) 'MaxRecords', -1) 'Tables', 'appusers') 'FetchSize', 100) 'Comment', "") 'BatchUpdateCount', 1) 'ShareConnection', .T.) 'Prepared', .F.) 'CompareMemo', .T.) 'FetchAsNeeded', .F.)
*!* Field Level Properties for RV_LOGIN * Props for the RV_LOGIN.cuserid field. =DBSetProp('RV_LOGIN.cuserid', 'Field', 'KeyField', .T.) =DBSetProp('RV_LOGIN.cuserid', 'Field', 'Updatable', .T.) =DBSetProp('RV_LOGIN.cuserid', 'Field', 'UpdateName', 'appusers.cuserid') =DBSetProp('RV_LOGIN.cuserid', 'Field', 'DataType', "C(30)") * Props for the RV_LOGIN.cfirst_name field. =DBSetProp('RV_LOGIN.cfirst_name', 'Field', 'KeyField', .F.) =DBSetProp('RV_LOGIN.cfirst_name', 'Field', 'Updatable', .T.) =DBSetProp('RV_LOGIN.cfirst_name', 'Field', 'UpdateName', 'appusers.cfirst_name') =DBSetProp('RV_LOGIN.cfirst_name', 'Field', 'DataType', "C(20)") * Props for the RV_LOGIN.clast_name field. =DBSetProp('RV_LOGIN.clast_name', 'Field', 'KeyField', .F.) =DBSetProp('RV_LOGIN.clast_name', 'Field', 'Updatable', .T.) =DBSetProp('RV_LOGIN.clast_name', 'Field', 'UpdateName', 'appusers.clast_name') =DBSetProp('RV_LOGIN.clast_name', 'Field', 'DataType', "C(25)") * Props for the RV_LOGIN.cpassword field. =DBSetProp('RV_LOGIN.cpassword', 'Field', 'KeyField', .F.) =DBSetProp('RV_LOGIN.cpassword', 'Field', 'Updatable', .T.) =DBSetProp('RV_LOGIN.cpassword', 'Field', 'UpdateName', 'appusers.cpassword') =DBSetProp('RV_LOGIN.cpassword', 'Field', 'DataType', "C(30)") * Props for the RV_LOGIN.dlastchanged field. =DBSetProp('RV_LOGIN.dlastchanged', 'Field', 'KeyField', .F.) =DBSetProp('RV_LOGIN.dlastchanged', 'Field', 'Updatable', .T.) =DBSetProp('RV_LOGIN.dlastchanged', 'Field', 'UpdateName', 'appusers.dlastchanged') =DBSetProp('RV_LOGIN.dlastchanged', 'Field', 'DataType', "D") * Props for the RV_LOGIN.ladministrator field. =DBSetProp('RV_LOGIN.ladministrator', 'Field', 'KeyField', .F.) =DBSetProp('RV_LOGIN.ladministrator', 'Field', 'Updatable', .T.)
=DBSetProp('RV_LOGIN.ladministrator', 'Field', 'UpdateName', 'appusers.ladministrator') =DBSetProp('RV_LOGIN.ladministrator', 'Field', 'DataType', "L") * Props for the RV_LOGIN.cgroup_id field. =DBSetProp('RV_LOGIN.cgroup_id', 'Field', 'KeyField', .F.) =DBSetProp('RV_LOGIN.cgroup_id', 'Field', 'Updatable', .T.) =DBSetProp('RV_LOGIN.cgroup_id', 'Field', 'UpdateName', 'appusers.cgroup_id') =DBSetProp('RV_LOGIN.cgroup_id', 'Field', 'DataType', "C(16) NOCPTRANS") * Props for the RV_LOGIN.moldpasswords field. =DBSetProp('RV_LOGIN.moldpasswords', 'Field', 'KeyField', .F.) =DBSetProp('RV_LOGIN.moldpasswords', 'Field', 'Updatable', .T.) =DBSetProp('RV_LOGIN.moldpasswords', 'Field', 'UpdateName', 'appusers.moldpasswords') =DBSetProp('RV_LOGIN.moldpasswords', 'Field', 'DataType', "M") * Props for the RV_LOGIN.linactive field. =DBSetProp('RV_LOGIN.linactive', 'Field', 'KeyField', .F.) =DBSetProp('RV_LOGIN.linactive', 'Field', 'Updatable', .T.) =DBSetProp('RV_LOGIN.linactive', 'Field', 'UpdateName', 'appusers.linactive') =DBSetProp('RV_LOGIN.linactive', 'Field', 'DataType', "L") ************************************************** ** View setup for RV_LOGINS ************************************************** Create SQL VIEW "RV_LOGINS" REMOTE CONNECTION x_CONNECTION ; AS SELECT * FROM applogin =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', =DBSetProp('RV_LOGINS', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'UpdateType', 1) 'WhereType', 3) 'FetchMemo', .T.) 'SendUpdates', .T.) 'UseMemoSize', 255) 'FetchSize', 100) 'MaxRecords', -1) 'Tables', 'applogin') 'FetchSize', 100) 'Comment', "") 'BatchUpdateCount', 1) 'ShareConnection', .T.) 'Prepared', .F.) 'CompareMemo', .T.) 'FetchAsNeeded', .F.)
*!* Field Level Properties for RV_LOGINS * Props for the RV_LOGINS.cuserid field. =DBSetProp('RV_LOGINS.cuserid', 'Field', 'KeyField', .T.) =DBSetProp('RV_LOGINS.cuserid', 'Field', 'Updatable', .T.) =DBSetProp('RV_LOGINS.cuserid', 'Field', 'UpdateName', 'applogin.cuserid') =DBSetProp('RV_LOGINS.cuserid', 'Field', 'DataType', "C(30)") * Props for the RV_LOGINS.tloggedin field. =DBSetProp('RV_LOGINS.tloggedin', 'Field', 'KeyField', .T.) =DBSetProp('RV_LOGINS.tloggedin', 'Field', 'Updatable', .T.) =DBSetProp('RV_LOGINS.tloggedin', 'Field', 'UpdateName', 'applogin.tloggedin') =DBSetProp('RV_LOGINS.tloggedin', 'Field', 'DataType', "T") =DBSetProp('RV_LOGINS.tloggedin', 'Field', 'DefaultValue', "DATETIME()") * Props for the RV_LOGINS.tloggedout field. =DBSetProp('RV_LOGINS.tloggedout', 'Field', 'KeyField', .F.) =DBSetProp('RV_LOGINS.tloggedout', 'Field', 'Updatable', .T.) =DBSetProp('RV_LOGINS.tloggedout', 'Field', 'UpdateName', 'applogin.tloggedout') =DBSetProp('RV_LOGINS.tloggedout', 'Field', 'DataType', "T")
* Props for the RV_LOGINS.tcleared field. =DBSetProp('RV_LOGINS.tcleared', 'Field', 'KeyField', .F.) =DBSetProp('RV_LOGINS.tcleared', 'Field', 'Updatable', .T.) =DBSetProp('RV_LOGINS.tcleared', 'Field', 'UpdateName', 'applogin.tcleared') =DBSetProp('RV_LOGINS.tcleared', 'Field', 'DataType', "T") * Props for the RV_LOGINS.cclearedby field. =DBSetProp('RV_LOGINS.cclearedby', 'Field', 'KeyField', .F.) =DBSetProp('RV_LOGINS.cclearedby', 'Field', 'Updatable', .T.) =DBSetProp('RV_LOGINS.cclearedby', 'Field', 'UpdateName', 'applogin.cclearedby') =DBSetProp('RV_LOGINS.cclearedby', 'Field', 'DataType', "C(30)") ************************************************** ** View setup for RV_APPINFO ************************************************** Create SQL VIEW "RV_APPINFO" REMOTE CONNECTION x_CONNECTION ; AS SELECT * FROM appinfo =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', =DBSetProp('RV_APPINFO', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'UpdateType', 1) 'WhereType', 3) 'FetchMemo', .T.) 'SendUpdates', .T.) 'UseMemoSize', 255) 'FetchSize', 100) 'MaxRecords', -1) 'Tables', 'appinfo') 'FetchSize', 100) 'Comment', "") 'BatchUpdateCount', 1) 'ShareConnection', .T.) 'Prepared', .F.) 'CompareMemo', .T.) 'FetchAsNeeded', .F.)
*!* Field Level Properties for RV_APPINFO * Props for the RV_APPINFO.cid field. =DBSetProp('RV_APPINFO.cid', 'Field', 'KeyField', .T.) =DBSetProp('RV_APPINFO.cid', 'Field', 'Updatable', .T.) =DBSetProp('RV_APPINFO.cid', 'Field', 'UpdateName', 'appinfo.cid') =DBSetProp('RV_APPINFO.cid', 'Field', 'DataType', "C(16) NOCPTRANS") =DBSetProp('RV_APPINFO.cid', 'Field', 'DefaultValue', "GUID()") =DBSetProp('RV_APPINFO.cid', 'Field', 'DisplayClass', "cactivedoc") =DBSetProp('RV_APPINFO.cid', 'Field', 'DisplayClassLibrary', "c:\vfe98\vfeframe\libs\ccontrls.vcx") * Props for the RV_APPINFO.nminpasswordlength field. =DBSetProp('RV_APPINFO.nminpasswordlength', 'Field', 'KeyField', .F.) =DBSetProp('RV_APPINFO.nminpasswordlength', 'Field', 'Updatable', .T.) =DBSetProp('RV_APPINFO.nminpasswordlength', 'Field', 'UpdateName', 'appinfo.nminpasswordlength') =DBSetProp('RV_APPINFO.nminpasswordlength', 'Field', 'DataType', "N(2)") =DBSetProp('RV_APPINFO.nminpasswordlength', 'Field', 'DefaultValue', "4") =DBSetProp('RV_APPINFO.nminpasswordlength', 'Field', 'DisplayClass', "cspinner") =DBSetProp('RV_APPINFO.nminpasswordlength', 'Field', 'DisplayClassLibrary', "c:\vfe98\vfeframe\libs\ccontrls.vcx") * Props for the RV_APPINFO.nminuseridlength field. =DBSetProp('RV_APPINFO.nminuseridlength', 'Field', 'KeyField', .F.) =DBSetProp('RV_APPINFO.nminuseridlength', 'Field', 'Updatable', .T.) =DBSetProp('RV_APPINFO.nminuseridlength', 'Field', 'UpdateName', 'appinfo.nminuseridlength') =DBSetProp('RV_APPINFO.nminuseridlength', 'Field', 'DataType', "N(2)")
=DBSetProp('RV_APPINFO.nminuseridlength', 'Field', 'DefaultValue', "3") =DBSetProp('RV_APPINFO.nminuseridlength', 'Field', 'DisplayClass', "cspinner") =DBSetProp('RV_APPINFO.nminuseridlength', 'Field', 'DisplayClassLibrary', "c:\vfe98\vfeframe\libs\ccontrls.vcx") * Props for the RV_APPINFO.nmaxlogins field. =DBSetProp('RV_APPINFO.nmaxlogins', 'Field', 'KeyField', .F.) =DBSetProp('RV_APPINFO.nmaxlogins', 'Field', 'Updatable', .T.) =DBSetProp('RV_APPINFO.nmaxlogins', 'Field', 'UpdateName', 'appinfo.nmaxlogins') =DBSetProp('RV_APPINFO.nmaxlogins', 'Field', 'DataType', "N(2)") =DBSetProp('RV_APPINFO.nmaxlogins', 'Field', 'DefaultValue', "1") =DBSetProp('RV_APPINFO.nmaxlogins', 'Field', 'DisplayClass', "cspinner") =DBSetProp('RV_APPINFO.nmaxlogins', 'Field', 'DisplayClassLibrary', "c:\vfe98\vfeframe\libs\ccontrls.vcx") * Props for the RV_APPINFO.nfailures field. =DBSetProp('RV_APPINFO.nfailures', 'Field', 'KeyField', .F.) =DBSetProp('RV_APPINFO.nfailures', 'Field', 'Updatable', .T.) =DBSetProp('RV_APPINFO.nfailures', 'Field', 'UpdateName', 'appinfo.nfailures') =DBSetProp('RV_APPINFO.nfailures', 'Field', 'DataType', "N(2)") =DBSetProp('RV_APPINFO.nfailures', 'Field', 'DefaultValue', "3") =DBSetProp('RV_APPINFO.nfailures', 'Field', 'DisplayClass', "cspinner") =DBSetProp('RV_APPINFO.nfailures', 'Field', 'DisplayClassLibrary', "c:\vfe98\vfeframe\libs\ccontrls.vcx") * Props for the RV_APPINFO.luniquepassword field. =DBSetProp('RV_APPINFO.luniquepassword', 'Field', 'KeyField', .F.) =DBSetProp('RV_APPINFO.luniquepassword', 'Field', 'Updatable', .T.) =DBSetProp('RV_APPINFO.luniquepassword', 'Field', 'UpdateName', 'appinfo.luniquepassword') =DBSetProp('RV_APPINFO.luniquepassword', 'Field', 'DataType', "L") =DBSetProp('RV_APPINFO.luniquepassword', 'Field', 'DefaultValue', ".T.") =DBSetProp('RV_APPINFO.luniquepassword', 'Field', 'DisplayClass', "ccheckbox") =DBSetProp('RV_APPINFO.luniquepassword', 'Field', 'DisplayClassLibrary', "c:\vfe98\vfeframe\libs\ccontrls.vcx") * Props for the RV_APPINFO.nchangepassword field. =DBSetProp('RV_APPINFO.nchangepassword', 'Field', 'KeyField', .F.) =DBSetProp('RV_APPINFO.nchangepassword', 'Field', 'Updatable', .T.) =DBSetProp('RV_APPINFO.nchangepassword', 'Field', 'UpdateName', 'appinfo.nchangepassword') =DBSetProp('RV_APPINFO.nchangepassword', 'Field', 'DataType', "N(4)") =DBSetProp('RV_APPINFO.nchangepassword', 'Field', 'DefaultValue', "0") =DBSetProp('RV_APPINFO.nchangepassword', 'Field', 'DisplayClass', "cspinner") =DBSetProp('RV_APPINFO.nchangepassword', 'Field', 'DisplayClassLibrary', "c:\vfe98\vfeframe\libs\ccontrls.vcx") * Props for the RV_APPINFO.ndefaultlevel field. =DBSetProp('RV_APPINFO.ndefaultlevel', 'Field', 'KeyField', .F.) =DBSetProp('RV_APPINFO.ndefaultlevel', 'Field', 'Updatable', .T.) =DBSetProp('RV_APPINFO.ndefaultlevel', 'Field', 'UpdateName', 'appinfo.ndefaultlevel') =DBSetProp('RV_APPINFO.ndefaultlevel', 'Field', 'DataType', "N(1)") =DBSetProp('RV_APPINFO.ndefaultlevel', 'Field', 'DefaultValue', "1") =DBSetProp('RV_APPINFO.ndefaultlevel', 'Field', 'DisplayClass', "coptiongroup") =DBSetProp('RV_APPINFO.ndefaultlevel', 'Field', 'DisplayClassLibrary', "c:\vfe98\vfeframe\libs\ccontrls.vcx") ************************************************** ** View setup for RV_SECURITYNAMES ************************************************** Create SQL VIEW "RV_SECURITYNAMES" REMOTE CONNECTION x_CONNECTION ; AS SELECT * FROM appnames
=DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES', =DBSetProp('RV_SECURITYNAMES',
'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View',
'UpdateType', 1) 'WhereType', 3) 'FetchMemo', .T.) 'SendUpdates', .T.) 'UseMemoSize', 255) 'FetchSize', 100) 'MaxRecords', -1) 'Tables', 'appnames') 'FetchSize', 100) 'Comment', "") 'BatchUpdateCount', 1) 'ShareConnection', .T.) 'Prepared', .F.) 'CompareMemo', .T.) 'FetchAsNeeded', .F.)
*!* Field Level Properties for RV_SECURITYNAMES * Props for the RV_SECURITYNAMES.cname field. =DBSetProp('RV_SECURITYNAMES.cname', 'Field', 'KeyField', .T.) =DBSetProp('RV_SECURITYNAMES.cname', 'Field', 'Updatable', .T.) =DBSetProp('RV_SECURITYNAMES.cname', 'Field', 'UpdateName', 'appnames.cname') =DBSetProp('RV_SECURITYNAMES.cname', 'Field', 'DataType', "C(40)") * Props for the RV_SECURITYNAMES.mdescription field. =DBSetProp('RV_SECURITYNAMES.mdescription', 'Field', 'KeyField', .F.) =DBSetProp('RV_SECURITYNAMES.mdescription', 'Field', 'Updatable', .T.) =DBSetProp('RV_SECURITYNAMES.mdescription', 'Field', 'UpdateName', 'appnames.mdescription') =DBSetProp('RV_SECURITYNAMES.mdescription', 'Field', 'DataType', "M") ************************************************** ** View setup for RV_RIGHTS ************************************************** Create SQL VIEW "RV_RIGHTS" REMOTE CONNECTION x_CONNECTION ; AS SELECT * FROM apprites WHERE apprites.cgroup_id = ?v_groups.cGroup_Id =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', =DBSetProp('RV_RIGHTS', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'UpdateType', 1) 'WhereType', 3) 'FetchMemo', .T.) 'SendUpdates', .T.) 'UseMemoSize', 255) 'FetchSize', 100) 'MaxRecords', -1) 'Tables', 'apprites') 'FetchSize', 100) 'Comment', "") 'BatchUpdateCount', 1) 'ShareConnection', .T.) 'Prepared', .F.) 'CompareMemo', .T.) 'FetchAsNeeded', .F.)
*!* Field Level Properties for RV_RIGHTS * Props for the RV_RIGHTS.cgroup_id field. =DBSetProp('RV_RIGHTS.cgroup_id', 'Field', 'KeyField', .T.) =DBSetProp('RV_RIGHTS.cgroup_id', 'Field', 'Updatable', .T.) =DBSetProp('RV_RIGHTS.cgroup_id', 'Field', 'UpdateName', 'apprites.cgroup_id') =DBSetProp('RV_RIGHTS.cgroup_id', 'Field', 'DataType', "C(16) NOCPTRANS") * Props for the RV_RIGHTS.cname field. =DBSetProp('RV_RIGHTS.cname', 'Field', 'KeyField', .T.)
=DBSetProp('RV_RIGHTS.cname', 'Field', 'Updatable', .T.) =DBSetProp('RV_RIGHTS.cname', 'Field', 'UpdateName', 'apprites.cname') =DBSetProp('RV_RIGHTS.cname', 'Field', 'DataType', "C(40)") * Props for the RV_RIGHTS.nrights field. =DBSetProp('RV_RIGHTS.nrights', 'Field', 'KeyField', .F.) =DBSetProp('RV_RIGHTS.nrights', 'Field', 'Updatable', .T.) =DBSetProp('RV_RIGHTS.nrights', 'Field', 'UpdateName', 'apprites.nrights') =DBSetProp('RV_RIGHTS.nrights', 'Field', 'DataType', "N(1)") ************************************************** ** View setup for RV_USERS ************************************************** Create SQL VIEW "RV_USERS" REMOTE CONNECTION x_CONNECTION ; AS SELECT * FROM appusers =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', =DBSetProp('RV_USERS', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'UpdateType', 1) 'WhereType', 3) 'FetchMemo', .T.) 'SendUpdates', .T.) 'UseMemoSize', 255) 'FetchSize', 100) 'MaxRecords', -1) 'Tables', 'appusers') 'FetchSize', 100) 'Comment', "") 'BatchUpdateCount', 1) 'ShareConnection', .T.) 'Prepared', .F.) 'CompareMemo', .T.) 'FetchAsNeeded', .F.)
*!* Field Level Properties for RV_USERS * Props for the RV_USERS.cuserid field. =DBSetProp('RV_USERS.cuserid', 'Field', 'KeyField', .T.) =DBSetProp('RV_USERS.cuserid', 'Field', 'Updatable', .T.) =DBSetProp('RV_USERS.cuserid', 'Field', 'UpdateName', 'appusers.cuserid') =DBSetProp('RV_USERS.cuserid', 'Field', 'DataType', "C(30)") * Props for the RV_USERS.cfirst_name field. =DBSetProp('RV_USERS.cfirst_name', 'Field', 'KeyField', .F.) =DBSetProp('RV_USERS.cfirst_name', 'Field', 'Updatable', .T.) =DBSetProp('RV_USERS.cfirst_name', 'Field', 'UpdateName', 'appusers.cfirst_name') =DBSetProp('RV_USERS.cfirst_name', 'Field', 'DataType', "C(20)") * Props for the RV_USERS.clast_name field. =DBSetProp('RV_USERS.clast_name', 'Field', 'KeyField', .F.) =DBSetProp('RV_USERS.clast_name', 'Field', 'Updatable', .T.) =DBSetProp('RV_USERS.clast_name', 'Field', 'UpdateName', 'appusers.clast_name') =DBSetProp('RV_USERS.clast_name', 'Field', 'DataType', "C(25)") * Props for the RV_USERS.cpassword field. =DBSetProp('RV_USERS.cpassword', 'Field', 'KeyField', .F.) =DBSetProp('RV_USERS.cpassword', 'Field', 'Updatable', .T.) =DBSetProp('RV_USERS.cpassword', 'Field', 'UpdateName', 'appusers.cpassword') =DBSetProp('RV_USERS.cpassword', 'Field', 'DataType', "C(30)") * Props for the RV_USERS.dlastchanged field. =DBSetProp('RV_USERS.dlastchanged', 'Field', 'KeyField', .F.) =DBSetProp('RV_USERS.dlastchanged', 'Field', 'Updatable', .T.) =DBSetProp('RV_USERS.dlastchanged', 'Field', 'UpdateName', 'appusers.dlastchanged') =DBSetProp('RV_USERS.dlastchanged', 'Field', 'DataType', "D") * Props for the RV_USERS.ladministrator field. =DBSetProp('RV_USERS.ladministrator', 'Field', 'KeyField', .F.)
=DBSetProp('RV_USERS.ladministrator', 'Field', 'Updatable', .T.) =DBSetProp('RV_USERS.ladministrator', 'Field', 'UpdateName', 'appusers.ladministrator') =DBSetProp('RV_USERS.ladministrator', 'Field', 'DataType', "L") * Props for the RV_USERS.cgroup_id field. =DBSetProp('RV_USERS.cgroup_id', 'Field', 'KeyField', .F.) =DBSetProp('RV_USERS.cgroup_id', 'Field', 'Updatable', .T.) =DBSetProp('RV_USERS.cgroup_id', 'Field', 'UpdateName', 'appusers.cgroup_id') =DBSetProp('RV_USERS.cgroup_id', 'Field', 'DataType', "C(16) NOCPTRANS") * Props for the RV_USERS.moldpasswords field. =DBSetProp('RV_USERS.moldpasswords', 'Field', 'KeyField', .F.) =DBSetProp('RV_USERS.moldpasswords', 'Field', 'Updatable', .T.) =DBSetProp('RV_USERS.moldpasswords', 'Field', 'UpdateName', 'appusers.moldpasswords') =DBSetProp('RV_USERS.moldpasswords', 'Field', 'DataType', "M") * Props for the RV_USERS.linactive field. =DBSetProp('RV_USERS.linactive', 'Field', 'KeyField', .F.) =DBSetProp('RV_USERS.linactive', 'Field', 'Updatable', .T.) =DBSetProp('RV_USERS.linactive', 'Field', 'UpdateName', 'appusers.linactive') =DBSetProp('RV_USERS.linactive', 'Field', 'DataType', "L") ************************************************** ** View setup for RV_RIGHTSTONAME ************************************************** Local vp_cGroup_id,vp_cName vp_cGroup_id = "A" vp_cName = "A" Create SQL VIEW "RV_RIGHTSTONAME" REMOTE CONNECTION x_CONNECTION ; AS SELECT * FROM apprites WHERE apprites.cgroup_id = ?vp_cGroup_id AND UPPER(apprites.cname) = UPPER(?vp_cName) =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', "vp_cGroup_id,'C';vp_cName,'C'") =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', =DBSetProp('RV_RIGHTSTONAME', 'View', 'UpdateType', 1) 'WhereType', 3) 'FetchMemo', .T.) 'SendUpdates', .F.) 'UseMemoSize', 255) 'FetchSize', 100) 'MaxRecords', -1) 'Tables', '') 'FetchSize', 100) 'ParameterList', 'Comment', "") 'BatchUpdateCount', 1) 'ShareConnection', .T.) 'Prepared', .F.) 'CompareMemo', .T.) 'FetchAsNeeded', .F.)
*!* Field Level Properties for RV_RIGHTSTONAME * Props for the RV_RIGHTSTONAME.cgroup_id field. =DBSetProp('RV_RIGHTSTONAME.cgroup_id', 'Field', 'KeyField', .T.) =DBSetProp('RV_RIGHTSTONAME.cgroup_id', 'Field', 'Updatable', .F.) =DBSetProp('RV_RIGHTSTONAME.cgroup_id', 'Field', 'UpdateName', 'apprites.cgroup_id') =DBSetProp('RV_RIGHTSTONAME.cgroup_id', 'Field', 'DataType', "C(16) NOCPTRANS") * Props for the RV_RIGHTSTONAME.cname field. =DBSetProp('RV_RIGHTSTONAME.cname', 'Field', 'KeyField', .T.)
=DBSetProp('RV_RIGHTSTONAME.cname', 'Field', 'Updatable', .F.) =DBSetProp('RV_RIGHTSTONAME.cname', 'Field', 'UpdateName', 'apprites.cname') =DBSetProp('RV_RIGHTSTONAME.cname', 'Field', 'DataType', "C(40)") * Props for the RV_RIGHTSTONAME.nrights field. =DBSetProp('RV_RIGHTSTONAME.nrights', 'Field', 'KeyField', .F.) =DBSetProp('RV_RIGHTSTONAME.nrights', 'Field', 'Updatable', .F.) =DBSetProp('RV_RIGHTSTONAME.nrights', 'Field', 'UpdateName', 'apprites.nrights') =DBSetProp('RV_RIGHTSTONAME.nrights', 'Field', 'DataType', "N(1)") ************************************************** ** View setup for RV_GROUPRIGHTS ************************************************** Local vp_cGroup_Id vp_cGroup_Id = "A" Create SQL VIEW "RV_GROUPRIGHTS" REMOTE CONNECTION x_CONNECTION ; AS SELECT * FROM apprites WHERE apprites.cgroup_id = ?vp_cGroup_Id =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', =DBSetProp('RV_GROUPRIGHTS', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'UpdateType', 1) 'WhereType', 3) 'FetchMemo', .T.) 'SendUpdates', .T.) 'UseMemoSize', 255) 'FetchSize', 100) 'MaxRecords', -1) 'Tables', 'apprites') 'FetchSize', 100) 'ParameterList', "vp_cGroup_Id,'C'") 'Comment', "") 'BatchUpdateCount', 1) 'ShareConnection', .T.) 'Prepared', .F.) 'CompareMemo', .T.) 'FetchAsNeeded', .F.)
*!* Field Level Properties for RV_GROUPRIGHTS * Props for the RV_GROUPRIGHTS.cgroup_id field. =DBSetProp('RV_GROUPRIGHTS.cgroup_id', 'Field', 'KeyField', .T.) =DBSetProp('RV_GROUPRIGHTS.cgroup_id', 'Field', 'Updatable', .T.) =DBSetProp('RV_GROUPRIGHTS.cgroup_id', 'Field', 'UpdateName', 'apprites.cgroup_id') =DBSetProp('RV_GROUPRIGHTS.cgroup_id', 'Field', 'DataType', "C(16) NOCPTRANS") * Props for the RV_GROUPRIGHTS.cname field. =DBSetProp('RV_GROUPRIGHTS.cname', 'Field', 'KeyField', .T.) =DBSetProp('RV_GROUPRIGHTS.cname', 'Field', 'Updatable', .T.) =DBSetProp('RV_GROUPRIGHTS.cname', 'Field', 'UpdateName', 'apprites.cname') =DBSetProp('RV_GROUPRIGHTS.cname', 'Field', 'DataType', "C(40)") * Props for the RV_GROUPRIGHTS.nrights field. =DBSetProp('RV_GROUPRIGHTS.nrights', 'Field', 'KeyField', .F.) =DBSetProp('RV_GROUPRIGHTS.nrights', 'Field', 'Updatable', .T.) =DBSetProp('RV_GROUPRIGHTS.nrights', 'Field', 'UpdateName', 'apprites.nrights') =DBSetProp('RV_GROUPRIGHTS.nrights', 'Field', 'DataType', "N(1)") ************************************************** ** View setup for RV_CURRENTLOGINS ************************************************** Local vp_cUserId vp_cUserId = "A"
Create SQL VIEW "RV_CURRENTLOGINS" REMOTE CONNECTION x_CONNECTION ; AS SELECT * FROM applogin WHERE applogin.cuserid = ?vp_cUserId AND applogin.tloggedout IS NULL AND applogin.tcleared IS NULL ORDER BY applogin.tloggedin DESC =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', =DBSetProp('RV_CURRENTLOGINS', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'View', 'UpdateType', 1) 'WhereType', 3) 'FetchMemo', .T.) 'SendUpdates', .T.) 'UseMemoSize', 255) 'FetchSize', 100) 'MaxRecords', -1) 'Tables', 'applogin') 'FetchSize', 100) 'ParameterList', "vp_cUserId,'C'") 'Comment', "") 'BatchUpdateCount', 1) 'ShareConnection', .T.) 'Prepared', .F.) 'CompareMemo', .T.) 'FetchAsNeeded', .F.)
*!* Field Level Properties for RV_CURRENTLOGINS * Props for the RV_CURRENTLOGINS.cuserid field. =DBSetProp('RV_CURRENTLOGINS.cuserid', 'Field', 'KeyField', .T.) =DBSetProp('RV_CURRENTLOGINS.cuserid', 'Field', 'Updatable', .F.) =DBSetProp('RV_CURRENTLOGINS.cuserid', 'Field', 'UpdateName', 'applogin.cuserid') =DBSetProp('RV_CURRENTLOGINS.cuserid', 'Field', 'DataType', "C(30)") * Props for the RV_CURRENTLOGINS.tloggedin field. =DBSetProp('RV_CURRENTLOGINS.tloggedin', 'Field', 'KeyField', .T.) =DBSetProp('RV_CURRENTLOGINS.tloggedin', 'Field', 'Updatable', .F.) =DBSetProp('RV_CURRENTLOGINS.tloggedin', 'Field', 'UpdateName', 'applogin.tloggedin') =DBSetProp('RV_CURRENTLOGINS.tloggedin', 'Field', 'DataType', "T") * Props for the RV_CURRENTLOGINS.tloggedout field. =DBSetProp('RV_CURRENTLOGINS.tloggedout', 'Field', 'KeyField', .F.) =DBSetProp('RV_CURRENTLOGINS.tloggedout', 'Field', 'Updatable', .T.) =DBSetProp('RV_CURRENTLOGINS.tloggedout', 'Field', 'UpdateName', 'applogin.tloggedout') =DBSetProp('RV_CURRENTLOGINS.tloggedout', 'Field', 'DataType', "T") * Props for the RV_CURRENTLOGINS.tcleared field. =DBSetProp('RV_CURRENTLOGINS.tcleared', 'Field', 'KeyField', .F.) =DBSetProp('RV_CURRENTLOGINS.tcleared', 'Field', 'Updatable', .T.) =DBSetProp('RV_CURRENTLOGINS.tcleared', 'Field', 'UpdateName', 'applogin.tcleared') =DBSetProp('RV_CURRENTLOGINS.tcleared', 'Field', 'DataType', "T") * Props for the RV_CURRENTLOGINS.cclearedby field. =DBSetProp('RV_CURRENTLOGINS.cclearedby', 'Field', 'KeyField', .F.) =DBSetProp('RV_CURRENTLOGINS.cclearedby', 'Field', 'Updatable', .T.) =DBSetProp('RV_CURRENTLOGINS.cclearedby', 'Field', 'UpdateName', 'applogin.cclearedby') =DBSetProp('RV_CURRENTLOGINS.cclearedby', 'Field', 'DataType', "C(30)")
After you run the above code and have also created the tables on the database, you should be able to USE these views. This is also how you can move the data from the local tables to the remote tables. If you simply use the views then you can append from the tables to the views, and issue a tableupdate() command.
Keep in mind that foreign key constraints are set up, so you will need to put the parent data before you put the child data. This means you must put groups on the server before you put users. You must also put appnames on the server before you put the apprights.
Gotchas
While this process worked a lot better than I expected there are a few issues that you should be aware of, but none of them are show-stoppers in my opinion.
Login Journal
Since SQL Server doesnt allow for empty dates, I set the logout and cleared dates to allow nulls. However, when you use the Purge button on the login journal of the login screen ALL records are erased. This is happening because the code basically says, delete all records where cleared or logout is not empty. Well, as we all know, NULL is not equal to empty, so all records are matched. I have reported this as a bug, but it is easy enough to fix yourself.
Were on it
The folks at F1 have promised that they know there are issues with the security system and will address it ASAP. We hope to se some security enhancements in service pack 3. At least creating I-layer classes and using those and the factory object so you wont have to modify c-layer classes to customize the security.
Summary
If you are going to use a SQL Server database and one of its benefits is security, dont loose that benefit. I have done most of the leg work for you here. All you need to do is make some backups, run a few scripts, and give it a go.